Nunjucksを使用したコンポーネントで静的サイトを構築する
公開: 2022-03-10最近は非常に人気があり、コンポーネントを使用してサイトを構築することは、あえて素晴らしいアイデアだと思います。 ページ全体を1つずつ作成するのではなく、コンポーネントのシステム(検索フォーム、記事カード、メニュー、フッターなど)を作成し、サイトをそれらのコンポーネントと組み合わせます。
ReactやVueなどのJavaScriptフレームワークは、このアイデアを非常に強調しています。 ただし、サイトの構築にクライアント側のJavaScriptをまったく使用しなくても、コンポーネントを使用して構築するというアイデアをあきらめる必要があるわけではありません。 HTMLプリプロセッサを使用することで、静的サイトを構築しながら、サイトとそのコンテンツを再利用可能なコンポーネントに抽象化することのすべてのメリットを享受できます。
静的サイトは最近大流行しており、ホストするのが高速で安全で安価であるため、当然のことながらそうです。 Smashing Magazineでさえ静的なサイトですが、信じられないかもしれません。
この手法を使用して最近構築したサイトを見ていきましょう。 私はCodePenProjectsを使用してビルドしました。これは、プリプロセッサとしてNunjucksを提供し、仕事に完全に対応していました。
一貫性のあるヘッダー、ナビゲーション、およびフッターを備えた4ページのサイト
これはマイクロサイトです。 数百ページを処理するために本格的なCMSは必要ありません。 対話性を処理するためにJavaScriptは必要ありません。 ただし、すべて同じレイアウトを共有する少数のページが必要です。
HTMLだけでは、これに対する適切な解決策はありません。 必要なのは輸入品です。 PHPのような言語は、 <?php include "header.php"; ?>
のようなものでこれを単純にします。 <?php include "header.php"; ?>
が、静的ファイルホストは(意図的に)PHPを実行せず、HTMLだけでは役に立ちません。 幸い、Nunjucksでインクルードを前処理できます。
ここで、ヘッダー、ナビゲーション、およびフッターを表すHTMLのチャンクを含むレイアウトを作成することは完全に理にかなっています。 Nunjucksテンプレートにはブロックの概念があり、レイアウトを使用するときにコンテンツをその場所に挿入できます。
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Power of Serverless</title> <link rel="stylesheet" href="/styles/style.processed.css"> </head> <body> {% include "./template-parts/_header.njk" %} {% include "./template-parts/_nav.njk" %} {% block content %} {% endblock %} {% include "./template-parts/_footer.njk" %} </body>
含まれているファイルの名前は_file.njk
のようになっていることに注意してください。 それは完全に必要というわけではありません。 header.html
またはicons.svg
の場合もありますが、1)アンダースコアで始まるファイルは、部分的であるという標準的な言い方では少しであるため、このように名前が付けられています。 CodePenプロジェクトでは、それはそれらが単独でコンパイルされようとしないことを意味します。 2) .njk
という名前を付けることで、必要に応じて、より多くのNunjucksを使用できます。
これらのビットには、特別なものはまったくありません。 これらは、4つのページのそれぞれで使用することを目的としたHTMLのほんの一部です。
<footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>
このようにして、1つの変更を加え、その変更を4ページすべてに反映させることができます。
4ページのレイアウトの使用
これで、4つのページのそれぞれをファイルにすることができます。 ただし、 index.njk
から始めましょう。これは、CodePen Projectsでは自動的に処理され、保存するたびにindex.html
ファイルが作成されます。
レイアウトを使用してそのブロックにコンテンツをドロップするためにindex.njk
に入れることができるものは次のとおりです。
{% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}
それは私たちに完全に機能するホームページを買うでしょう! 良い! 4ページのそれぞれがまったく同じことを行うことができますが、ブロックに異なるコンテンツを配置し、管理しやすい小さな4ページのサイトを用意しています。
ちなみに、コンポーネントを再利用するこれらの小さなチャンクを呼び出すかどうかはわかりません。 効率的で、レイアウトをチャンクに分割しているだけです。 コンポーネントは、データを受け取り、そのデータを使用して独自のバージョンを出力する、再利用可能なチャンクのようなものだと思います。 それに到達します。
アクティブナビゲーションを作成する
4つのページで同じHTMLのチャンクを繰り返したので、現在のページを識別するために個々のナビゲーションアイテムに一意のCSSを適用することは可能ですか? JavaScriptを使用してwindow.location
などを確認することもできますが、JavaScriptを使用せずにこれを行うことはできます。 秘訣は、各ページに固有の<body>
にclass
を配置し、それをCSSで使用することです。
_layout.njk
、本体にクラス名が変数として出力されます。
<body class="{{ body_class }}">
次に、個々のページでそのレイアウトを呼び出す前に、その変数を設定します。
{% set body_class = "home" %} {% extends "_layout.njk" %}
ナビゲーションが次のように構成されているとしましょう
<nav class="site-nav"> <ul> <li class="nav-home"> <a href="/"> Home </a> ...
これで、そのリンクをターゲットにして、必要に応じて次のようにして特別なスタイルを適用できます。
body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ }
ああ、それらのアイコン? これらは、私がフォルダーに入れて次のように含めた個々の.svg
ファイルです。
{% include "../icons/cloud.svg" %}
そしてそれは私がそれらを次のようにスタイリングすることを可能にします:
svg { fill: white; }
内部のSVG要素にfill
属性がまだないことを前提としています。
Markdownでのコンテンツのオーサリング
私のマイクロサイトのホームページには、大量のコンテンツが含まれています。 私は確かにそれをHTML自体で記述して維持することができましたが、そのタイプのものをMarkdownに任せるのが良い場合もあります。 Markdownは、コピーが多いと、書きやすく、見やすくなります。
これはCodePenプロジェクトでは非常に簡単です。 .md
で終わるファイルを作成しました。このファイルは自動的にHTMLに処理され、 index.njk
ファイルに含まれます。
{% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}
実際のコンポーネントの構築
コンポーネントを、データを渡して自分自身を作成する反復可能なモジュールと考えてみましょう。 Vueのようなフレームワークでは、テンプレート化されたHTML、スコープ付きCSS、およびコンポーネント固有のJavaScriptの分離されたビットである単一のファイルコンポーネントを操作します。 それはとてもクールですが、私たちのマイクロサイトにはそれほど凝ったものは必要ありません。
単純なテンプレートに基づいていくつかの「カード」を作成する必要があるため、次のようなものを作成できます。
Nunjucksでそのような繰り返し可能なコンポーネントを構築するには、マクロと呼ばれるものを使用する必要があります。 マクロはおいしくシンプルです。 HTMLに関数があるかのようです!
{% macro card(title, content) %} <div class="card"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> {% endmacro %}
次に、必要に応じてそれを呼び出します。
{{ card('My Module', 'Lorem ipsum whatever.') }}
ここでの全体的な考え方は、データとマークアップを分離することです。 これにより、かなり明確で具体的なメリットが得られます。
- HTMLに変更を加える必要がある場合は、マクロで変更でき、そのマクロを使用するすべての場所で変更されます。
- データはマークアップに絡まない
- データはどこからでも取得できます。 上記で行ったように、データをマクロの呼び出しに直接コーディングします。 または、JSONデータを参照してループすることもできます。 そのJSONデータが一種のヘッドレスCMS、ビルドプロセス、サーバーレス関数、cronジョブなどから取得されるセットアップを想像することもできると思います。
これで、データとマークアップを組み合わせたこれらの繰り返し可能なカードができました。必要なものだけです。
必要な数のコンポーネントを作成する
このアイデアを取り入れて実行することができます。 たとえば、Bootstrapが本質的にHTMLパターンに従って使用するCSSの集まりであると想像してみてください。 これらの各パターンをマクロにして、必要に応じて呼び出し、基本的にフレームワークをコンポーネント化することができます。
必要に応じて、ある種のアトミックデザイン哲学を取り入れてコンポーネントをネストできます。 Nunjucksはロジックも提供します。つまり、さまざまなデータを渡すだけで条件付きコンポーネントとバリエーションを作成できます。
私が作成した単純なサイトでは、サイトのアイデアセクションに異なるマクロを作成しました。これは、データとカードのデザインがわずかに異なるためです。
静的サイトに対するクイックケース
ほとんどのサイトはコンポーネントベースのアーキテクチャの恩恵を受けていると私は主張するかもしれませんが、静的であるために適切なのは一部のサイトだけです。 私は、バックエンド言語を持つことが適切で有用な多くのサイトで働いています。
私のサイトの1つであるCSS-Tricksには、フォーラム、コメント、eコマースなどのやや複雑な権限システムを使用したユーザーログインのようなものがあります。 これらのことのどれもが静的に動作するという考えを完全に止めるものではありませんが、データベースとバックエンド言語を使用できることを嬉しく思います。 それは私が必要なものを構築するのを助け、物事を一つの屋根の下に保ちます。
前進し、静的な生活を受け入れましょう!
この記事で行った方法でビルドすることの利点の1つは、最終結果が静的ファイルの束にすぎないことです。 ホストが簡単で、高速で、安全です。 それでも、開発者に優しい方法での作業をあきらめる必要はありませんでした。 このサイトは、将来、簡単に更新および追加できるようになります。
- 最後のプロジェクトは、フロントエンド開発者向けのサーバーレスの力(https://thepowerofserverless.info/)と呼ばれるマイクロサイトです。
- 静的ファイルホスティングは、私に言わせれば、サーバーレスムーブメントの一部です。
- すべてのコードをCodePenで直接見ることができます(さらには自分用にコピーをフォークすることもできます)。 これは、CodePenプロジェクトを使用して、CodePen上で完全に構築、保守、およびホストされます。
- CodePen Projectsは、ここで説明したすべてのNunjucksの処理に加えて、サイトで利用したSass処理や画像ホスティングなども処理します。 たとえば、GulpまたはGruntベースのビルドプロセスをローカルで使用して同じことを複製できます。 これが、スピンアップできるような定型的なプロジェクトです。