アストロレシピ収集ウェブサイト-パート3カテゴリーフィルタページ


我々は、我々の新しいアストロレシピウェブサイトでかなりの進歩をしています.
これまでのところ、以下のような作業を行いました.
  • Setup the recipe collection page and single page
  • Show the five latest recipes on our homepage
  • そして今日、私たちは特定のタグページを作成するでしょう.
    これらのタグのページは、人々が探しているレシピを見つけるための有用な概要になります.
    我々のレシピウェブサイトのためのタグ概要ページの若干の例は、そうかもしれません:
  • meal type : すべての朝食のレシピを表示
  • course : 私はすべてのサラダのリストが欲しい
  • diet : すべての絶対菜食主義のレシピを見せてください
  • main ingredient : すべての豆腐料理のリストを見たい
  • カテゴリフィルタページの作成


    しばらくして、実際のフィルターページについての最後のURL構造を考えましょう.
    お願いしますrecipes/breakfast and recipes/salads 私たちのSEOの長い実行に最適です.
    それから、我々は前進しなければならなくて、我々recipes 我々が持っているすべての特定のカテゴリのコレクションになるページ.
    お返しに、我々は現在のレシピページを持つことを選ぶことができますrecipes/all エンドポイント.
    なぜ我々はそれをしたいですか?
    まあ、それは我々の仕事を我々のエンドクライアントを助けることができる限り.誰かが特定のレシピを探しており、できるだけ早くその特定のレシピを見つけることに導かれることでしょう.だから我々は試してみて、それらをすべてのレシピを表示する前にカテゴリページを表示することによってそれらを助ける.

    すべてのエンドポイントにレシピコレクションを移動する


    最初に我々の既存のレシピコレクションを動かしましょうall URL.
    このためには、新しいフォルダを作成する必要がありますrecipes . これは新らしいrecipes 我々のURLの構造
    このフォルダの中にall そして古いものを動かす[...page].astro この新しいフォルダにファイルします.
    これを開く[...page].astro ファイルを取り出し、内容を1つのレベルから高くします.
    // before
    const allRecipes = Astro.fetchContent('./recipe/*.md');
    
    // after
    const allRecipes = Astro.fetchContent('./../../recipe/*.md');
    
    大丈夫、これを試してみて、私たちのアストロアプリを実行してみましょうnpm start .

    それは一歩一歩です.

    特定のフィルターエンドポイントの作成


    今、我々は先に行き、特定のフィルタエンドポイントを作成したい.URLを同じレベルにしたいので、これは少しトリッキーです.
    いくつかの例
  • /recipes/breakfast
  • /recipes/vegan
  • /recipes/roast
  • /recipes/roast/2
  • /recipes/meat-and-chicken
  • フィルタが複数のフィルタのために同じキーを使用するためにユニークであるので、これは少し難しいです.

    Note: Keep an eye out for duplicate key usage in your recipes, as it will overwrite the collections.


    私たちはまず[slug] 我々のレシピフォルダの中のフォルダは、これを働かせます.これはroast 例えば、
    このフォルダの中で[...page].astro これが我々のPaginationモデルとして役立つように.
    まず、フロントエンドのセクションで実行できるコードを定義しましょう.
    ---
    export function getStaticPaths({paginate}) {
      // All our code
    }
    const { page, filter } = Astro.props;
    ---
    
    このセクションでは、私たちのコレクションを定義し、同じ標準として我々はall collection .
    その後、我々はすべてのフィルタリングを開始することができますので、すべてのレシピをロードする必要があります.
    const allRecipes = Astro.fetchContent('./../../recipe/*.md');
    
    次に、Markdownファイルにあるすべてのフィルタキーを定義しましょう.使用したことを覚えておいてください.meal_type , course , diet , and main_ingredient .
    const filterKeys = ['meal_type', 'course', 'diet', 'main_ingredient'];
    
    これらのキーは、各レシピのMarkdownファイルから特定の値を取得するために使用されます.

    すべてのユニークなフィルタ値の取得


    それから、すべてのフィルタ値を得ましょう.
    各フィルタキーは一意の値の配列になるはずです.
    取得したい出力は以下のようになります.
    ['Dinner', 'Roast', 'Healthy', 'Meat and chicken', 'Breakfast', 'vegan', 'Banana'];
    
    これを小さなステップに分けて始めよう.
    ステップ1はJavaScript reduce function を返します.
    const filter = allRecipes.reduce((curr, recipe) => {
      filterKeys.forEach((key) => {
        if (!recipe[key]) return;
        curr.push(recipe[key]);
      });
      return curr;
    }, []);
    
    減らされた機能は我々のレシピの各々を通してループします、そして、各々の記録のために、我々は定義されるフィルタ・キーを通して輪になります、そして、そのレシピがこのキーの値を持っているかどうかチェックします.
    そうでなければ、そのループを返します.その他の値を現在の配列にプッシュします.
    この関数はすべての値の配列を返します.
    ['Dinner', 'Roast', 'Healthy', 'Dinner'];
    

    Note: Do you see the double Dinner value?


    ユニークな値をフィルタリングするにはJavaScript Set method .
    単純に前のメソッドをset returnでラップします.
    const filter = new Set(
      allRecipes.reduce((curr, recipe) => {
        filterKeys.forEach((key) => {
          if (!recipe[key]) return;
          curr.push(recipe[key]);
        });
        return curr;
      }, [])
    );
    
    しかし、新たな問題が発生する.これは現在、JavaScriptセットオブジェクトであり、配列の動作として正確に動作しません.
    私たちはJavaScript spread operator setを配列に変換するには
    const filters = [
      ...new Set(
        allRecipes.reduce((curr, recipe) => {
          filterKeys.forEach((key) => {
            if (!recipe[key]) return;
            curr.push(recipe[key]);
          });
          return curr;
        }, [])
      ),
    ];
    
    はい、今我々はすべてのレシピのための独自のフィルタの値を持っている!

    スラグ機能の作成


    上で、我々は我々がユニークな価値の配列を得ることができると確信しました;しかし、我々のような結果を得るMeat and chicken .
    肉や鶏肉とは何も悪いが、我々は我々のURLに配置することはできません.
    代わりに、次のようにします.meat-and-chicken .
    それを達成するために、スラグ機能を定義しましょう.この関数は文字列をとり、その文字列のスラッグバージョンを返します.
    const slugify = (url) =>
      url
        .toLowerCase()
        .replace(/[^a-z0-9 -]/g, '')
        .replace(/\s+/g, '-');
    
    この機能を中断するには、拡張バージョンをコメントで見ましょう.
    const slugify = (url) => {
      return url
        .toLowerCase() // Conver to lowercase
        .replace(/[^a-z0-9 -]/g, '') // Remove all special characters
        .replace(/\s+/g, '-'); // Convert spaces to dashes
    };
    

    実際のアストロコレクションコード


    右、我々は必要なすべての要素があります.先に行き、アストロでこのコレクションを作成しましょう.
    私たちのコレクションにreturnオブジェクトを定義し、プロパティを記述することから始める必要があります.
    return filters.map((filter) => {
      const filteredPosts = allRecipes.filter((recipe) =>
        filterKeys.some((key) => recipe[key] === filter)
      );
    
      return paginate(filteredPosts, {
        params: {slug: slugify(filter)},
        props: {filter},
        pageSize: 5,
      });
    });
    
    そこにはたくさんある.項目ごとに何が起こるか見ましょう.
  • filter.map : 我々は、スラグページを作成するために、それぞれのフィルタの上にループします.
  • filteredPosts : これらは特定のフィルタにマッチするポストです
  • paginate : このコレクションのページ設定を有効にする
  • params : このルートのためにスラグ(スラグ化)を加えてください
  • props : 我々は、フィルタを我々のHTMLで使用する支柱として送ります
  • pageSize : ページにつき5つのアイテムだけを示してください
  • 結果のレンダリング


    これらの結果を使用するには、いくつかのHTMLコードを追加しましょう[...page].astro 最後のファイル--- セクション.
    <html lang="en">
      <head>
        <title>Pagination Example</title>
      </head>
      <body>
        <h1>All {filter} Recipes</h1>
        {page.data.map((recipe) => (
          <a href={recipe.url}>
            <h1>{recipe.title}</h1>
          </a>
        ))}
        <footer>
          <h4>
            Page {page.current} / {page.last}
          </h4>
          <nav class="nav">
            <a class="prev" href={page.url.prev || '#'}>
              Prev
            </a>
            |<a class="next" href={page.url.next || '#'}>
              Next
            </a>
          </nav>
        </footer>
      </body>
    </html>
    
    ここでは、我々は同じようにアプローチを使用することがわかりますall ページ.
    その結果、次のようになります.

    完全なコード例に興味があるならば、あなたは以下のことを見つけることができますGitHub repo .

    読んでいただきありがとうございます、接続しましょう!


    私のブログを読んでくれてありがとう.私の電子メール会報を購読して、接続してくださいFacebook or