使用 Nunjucks 使用組件構建靜態站點
已發表: 2022-03-10這幾天很流行,我敢說一個該死的好主意,用組件構建網站。 我們不是一個一個地構建整個頁面,而是構建一個組件系統(想想:搜索表單、文章卡片、菜單、頁腳),然後將站點與這些組件拼湊在一起。
像 React 和 Vue 這樣的 JavaScript 框架非常強調這個想法。 但是,即使您根本不使用任何客戶端 JavaScript 來構建站點,也不意味著您必須放棄使用組件構建的想法! 通過使用 HTML 預處理器,我們可以構建一個靜態站點,並且仍然可以獲得將站點及其內容抽象為可重用組件的所有好處。
靜態網站如今風靡一時,這是理所當然的,因為它們快速、安全且託管成本低廉。 甚至 Smashing Magazine 也是一個靜態網站,信不信由你!
讓我們來看看我最近使用這種技術建立的一個網站。 我使用 CodePen Projects 來構建它,它提供 Nunjucks 作為預處理器,非常適合這項工作。
具有一致頁眉、導航和頁腳的四頁網站
這是一個微型網站。 它不需要一個成熟的 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 東西。
這些位都沒有任何特別之處。 它們只是用於我們四個頁面中的每個頁面的一小部分 HTML。
<footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>
通過這種方式,我們可以進行一次更改,並將更改反映在所有四個頁面上。
使用四個頁面的佈局
現在我們的四個頁面中的每一個都可以是一個文件。 不過,讓我們從index.njk
開始,在 CodePen 項目中,它會在您每次保存時自動處理並創建一個index.html
文件。
這是我們可以放入index.njk
以使用佈局並在該塊中刪除一些內容的內容:
{% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}
這將為我們購買一個功能齊全的主頁! 好的! 四個頁面中的每一個都可以做同樣的事情,但在塊中放置不同的內容,我們有一個易於管理的小四頁站點。
作為記錄,我不確定我是否會將這些小塊稱為我們重用組件。 我們只是提高效率並將佈局分解成塊。 我認為一個組件更像是一個可重用的塊,它接受數據並使用該數據輸出其自身的唯一版本。 我們會解決的。
進行主動導航
既然我們已經在四個頁面上重複了相同的 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.') }}
這裡的整個想法是分離 data 和 markup 。 這給了我們一些非常明確和切實的好處:
- 如果我們需要對 HTML 進行更改,我們可以在宏中進行更改,並且在使用該宏的任何地方都會更改。
- 數據沒有與標記糾纏在一起
- 數據可能來自任何地方! 就像我們在上面所做的那樣,我們將數據直接編碼到對宏的調用中。 或者我們可以引用一些 JSON 數據並對其進行循環。 我敢肯定,您甚至可以想像這樣一種設置,其中 JSON 數據來自某種無頭 CMS、構建過程、無服務器功能、cron 作業或其他任何東西。
現在我們有了這些結合了數據和標記的可重複卡片,正是我們所需要的:
製作盡可能多的組件
你可以接受這個想法並堅持下去。 例如,想像一下 Bootstrap 本質上是一堆你遵循 HTML 模式使用的 CSS。 您可以將這些模式中的每一個都設為宏,並根據需要調用它們,本質上是對框架進行組件化。
如果您願意,您可以嵌套組件,採用一種原子設計理念。 Nunjucks 也提供邏輯,這意味著您可以通過傳入不同的數據來創建條件組件和變體。
在我製作的簡單網站中,我為網站的想法部分製作了不同的宏,因為它涉及略有不同的數據和略有不同的卡片設計。
針對靜態站點的快速案例
我可能會爭辯說,大多數網站都受益於基於組件的架構,但只有一些網站適合靜態。 我在很多網站上工作,在這些網站上使用後端語言是合適且有用的。
我的一個網站,CSS-Tricks,有一些東西,比如用戶登錄,權限系統有點複雜:論壇、評論、電子商務。 雖然這些事情都沒有完全阻止靜態工作的想法,但我經常很高興我有一個數據庫和後端語言可以使用。 它可以幫助我構建我需要的東西,並將東西放在一個屋簷下。
前進,擁抱靜態生活!
請記住,以我們在本文中所做的方式進行構建的好處之一是最終結果只是一堆靜態文件。 易於託管、快速且安全。 然而,我們不必放棄以對開發人員友好的方式工作。 該站點將來易於更新和添加。
- 最後一個項目是一個名為 The Power of Serverless for Front-End Developers 的微型網站 (https://thepowerofserverless.info/)。
- 如果您問我,靜態文件託管是無服務器運動的一部分。
- 您可以直接在 CodePen 上查看所有代碼(甚至為自己複製一份)。 它使用 CodePen 項目完全在 CodePen 上構建、維護和託管。
- CodePen Projects 處理我們在這裡談到的所有 Nunjucks 的東西,以及 Sass 處理和圖像託管之類的東西,我在網站上利用了這些東西。 您可以在本地複制相同的內容,例如,基於 Gulp 或 Grunt 的構建過程。 這是一個樣板項目,您可以啟動它。