Eleventyを始めとする静的サイトジェネレーター(SSG)の登場により、これまで以上に簡単に、スタイリッシュで効率的な静的サイトを作成できるようになりました。

この記事では、Eleventyの使い方をご紹介し、サーバーサイド言語やデータベースを使わずに、魅力的で機能的な静的ポートフォリオサイトを作成していきます。

また、静的サイトをGitHubリポジトリから、Kinstaの静的サイトホスティングサービスに直接デプロイし、無料で利用できる「.kinsta.page」ドメインで素早くサイトを公開する方法も見ていきます。

Eleventyで構築した静的ポートフォリオサイトのデモはこちらでご覧いただけます。

クールな印象の静的ポートフォリオサイト
クールな印象の静的ポートフォリオサイト

より詳しい情報については、GitHubリポジトリを参照してください。

Eleventyとは

Eleventyは「11ty」としても知られる静的サイトジェネレーターです。データベースやバックエンドのプログラミング言語を必要とせず、HTMLCSSJavaScriptでウェブサイトを作成できます。

Eleventyはそのシンプルさと柔軟性で知られており、1つのテンプレート言語やフレームワークに縛られません。10以上のテンプレート言語をサポートし、1つのプロジェクトで複数のテンプレート言語も使用できます。

Eleventyのテンプレート言語
Eleventyのテンプレート言語

EleventyはほとんどのSSGと同様に、再利用可能なコンポーネントを使用して静的サイトのコンテンツを構築します。それぞれのページ用に完全なHTMLドキュメントを作成する必要はありません。

Eleventyのインストール方法

Eleventyは簡単にインストールできます。

  1. コンピュータにNode.jsがインストールされていることを確認してください。ターミナルでnode -vコマンドを実行して確認できます。インストールされていなければ、こちらの記事を参考に、Node.jsをインストールしてください。
  2. プロジェクト用にディレクトリを作成します。
  3. ターミナルを開き、プロジェクトのディレクトリでnpm init -yコマンドを実行してNode.jsプロジェクトを初期化し、デフォルト設定のpackage.jsonファイルを作成します。
  4. npm install @11ty/eleventy --save-devコマンドを実行して、プロジェクトに開発依存パッケージをインストールします。
  5. これでEleventyがインストールされます。プロジェクトディレクトリでnpx @11ty/eleventyコマンドを実行すると、Eleventyを起動できます。プロジェクトフォルダ内の_siteディレクトリ(または設定したディレクトリ)に、生成したサイトファイルが出力されます。

注意npx @11ty/eleventyコマンドを実行すると、次のように表示されます。

[11ty] Wrote 0 files in 0.01 seconds (v2.0.0)

まだプロジェクトフォルダにテンプレートがないため「0 files」と表示されます。

Eleventyコマンドと構成

以上でEleventyプロジェクトを作成できましたが、これで終わりではありません。静的サイトを作成してブラウザからアクセスできるようにするまでには、いくつかの構成を作成し、基本的なコマンドを学習する必要があります。

Eleventyコマンド

Eleventyの主なコマンドをご紹介します。

  • npx @11ty/eleventy:サイトを構築。結果は_siteフォルダ、または出力ディレクトリとして設定した任意のフォルダに出力される。
  • npx @11ty/eleventy --serve:ブラウザでサイトをプレビューできるようにローカルサーバーを起動。サイトに変更を加えるとプロジェクトは自動的にリビルドされ、ブラウザ上で更新される。
  • npx @11ty/eleventy --serve --port=8081:サーバーがリッスンするカスタムポートを指定して、Eleventyサーバーを起動。
  • npx @11ty/eleventy --watch:プロジェクトファイルの変更を監視し、自動的にサイトをリビルド。

コマンドを覚える必要はありません。package.jsonファイルのscriptsオブジェクトに一般的なコマンドとして追加することができます。

"scripts": {
    "build": "npx @11ty/eleventy",
    "start": "npx @11ty/eleventy --serve",
    "watch": "npx @11ty/eleventy --watch"
  },

これで、npx @11ty/eleventy --serveの代わりにnpm startを使用して、アプリケーションを実行し、npx @11ty/eleventyの代わりにnpm run buildを使用してビルドできます。

Eleventyで静的サイトを構成する方法

Eleventyはデフォルトで構成は不要ですが、例えば以下のような柔軟な構成があります。

  • input:プロジェクトファイルのディレクトリを指定。ベストプラクティスは、src
  • output:ビルドしたサイトを出力するディレクトリを指定。デフォルトでは、_siteフォルダに出力される。(変更は不要)。
  • templateFormats:テンプレートとして処理するファイル拡張子を指定。デフォルトでは、.html.njk.mdファイルをテンプレートとして処理する。

以上は、Eleventyで使用できるコマンドと構成のほんの一部です。Eleventyプロジェクトを構成するには、プロジェクトのルートディレクトリに.eleventy.jsファイルを作成してください。次に以下のコードをファイルに貼り付け、プロジェクトの入力ディレクトリを含む構造を設定します。

module.exports = function (eleventyConfig) {
    return {
        dir: {
            input: 'src',
        },
    };
};

注意)引数として渡されるeleventyConfigには、多くの構成を設定できます。この記事の後半でご紹介していきます。

Eleventyサイトをプレビューする方法

ここまでで、Eleventyの静的サイトのプレビューに使用する主なコマンドをご説明しました。しかし、テンプレートファイルがないため、npm run buildnpx @11ty/eleventy)コマンドを実行してもまだ何も出力されません。

プロジェクトのルートフォルダにsrcフォルダを作成し、index.htmlなどのテンプレートファイルを作成するか、好みのテンプレート言語を使用してホームページを作成します。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Eleventy Static Site</title>
    </head>
    <body>
        Hello World!
    </body>
</html>

npm run buildコマンドを実行すると、_siteフォルダが作成され、静的ファイルが生成されます。ブラウザからアクセスし、ホットリロード機能を有効にするには、npx @11ty/eleventy --serveコマンド、または先に構成したようにnpm startコマンドを実行します。サイトにはhttp://localhost:8080/でアクセスできます。

Eleventyでの静的ポートフォリオサイト作成方法

Eleventyで静的サイトを作成する方法がわかったところで、次にポートフォリオプロジェクトを作成してみます

Eleventyプロジェクトはゼロから作成するか、このプロジェクト用の画像、CSS、コンテンツを含むスターターファイルを使用して、作業をスピードアップすることも可能です。GitHubで「Use this template(このテンプレートを使用)」>「Create a new repository(新しいリポジトリを作成)」を選択して、アセットと初期設定ファイルを自分の新しいリポジトリにコピーし、ローカルマシンにダウンロードしてください。

プロジェクトのフォルダ構造は以下の通りです。

├── node_modules/
├── public/
├── src/
     ├── _includes
     ├── layouts
     ├── assets
     ├── css
     ├── projects
     └── index.njk
├── .eleventy.js
├── .gitignore
├── package.lock.json
└── package.json

Eleventyでのテンプレートの使用方法

Eleventyを使用する際には、理解しておきたい3つの主要なテンプレートがあります。テンプレートはNunjucksで作成し、変数、ループ、条件分岐、その他のロジックを定義して、ページのコンテンツを動的に生成できます。

  • ページテンプレート:ウェブサイトの個々のページの構造とコンテンツを定義。
  • レイアウトテンプレート:ウェブサイトのページ全体の構造とデザインを定義。レイアウトテンプレートには通常、ヘッダー、フッター、ナビゲーションメニュー、サイドバーなど、複数のページで共有される共通の要素が含まれる。
  • パーシャルテンプレート:ウェブサイトのHTMLマークアップの再利用可能な小さなセクションを定義。ヘッダー、フッター、ナビゲーションメニュー、サイドバーなどの共通要素の定義に使用され、レイアウトテンプレートやページテンプレートに挿入される。

各テンプレートタイプの概要を理解したら、早速静的ポートフォリオサイトのテンプレートを作成しましょう。

Eleventyでのレイアウトの作成方法

srcディレクトリの中に_includesディレクトリを作成し、すべてのレイアウトテンプレートとパーシャルテンプレートを格納します。

さらに、すべてのテンプレートの整理のためにlayoutsフォルダを作成します。ここではNunjucksなどの好きなテンプレート言語を使用できます。

すべてのページの汎用レイアウトのため、layoutsbase.njkファイルを作成します。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="icon" href="/assets/favicon.jpeg" />
        <link
            rel="stylesheet"
            href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"
            integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
        />
        <link rel="stylesheet" href="/css/global.css" />
        <title>J.'s Portfolio</title>
    </head>
    <body>
        <div>
            {{ content | safe }}
        </div>
    </body>
</html>

上のコードは、汎用のHTMLマークアップを作成し、CDNからインクルードしてFont Awesomeのアイコンを利用します。またcontent変数を渡し、このレイアウトを使用するすべてのページのコンテンツをここに挿入します。

しかし、これがレイアウトのすべてではありません。レイアウトにはナビゲーションバーやフッターなど、すべてのページに表示されるセクションがあります。セクションごとにパーシャルテンプレートを作成します。

Eleventyでのパーシャルテンプレートの使用

すべてのパーシャルテンプレートは、_includesディレクトリに保存されます。整理の便宜のため、_includesディレクトリ内にcomponentsフォルダを作成します。Navbarパーシャルテンプレートとしてnavbar.njkを作成し、以下のコードを記述します。

<div class="nav-container">
    <div class="logo">
        <a href="/">
            J.
        </a>
    </div>
    <div class="nav">
        <a href="/projects" class="link">
            Projects
        </a>
        <a href="https://docs.google.com/document/d/10ZosQ38Z3804KYPcb_aZp9bceoXK-q3GrkHjYshqIRE/edit?usp=sharing" class="cta-btn">Resume</a>
    </div>
</div>

次にFooterパーシャルテンプレートとして、footer.njkを作成します。

<hr />
<div class="footer-container">
    <p>© 2023 Joel's Portfolio</p>
    <div class="social_icons">
        <a
            href="https://twitter.com/olawanle_joel"
            aria-label="Twitter"
            target="_blank"
            rel="noopener noreferrer"
        >
            <i class="fa-brands fa-twitter"></i>
        </a>
        <a
            href="https://github.com/olawanlejoel"
            aria-label="GitHub"
            target="_blank"
            rel="noopener noreferrer"
        >
            <i class="fa-brands fa-github"></i>
        </a>
        <a
            href="https://www.linkedin.com/in/olawanlejoel/"
            aria-label="LinkedIn"
            target="_blank"
            rel="noopener noreferrer"
        >
            <i class="fa-brands fa-linkedin"></i>
        </a>
    </div>
</div>

{% include %}ステートメントを使用してパーシャルテンプレートをページテンプレート、またはレイアウトテンプレートに追加します。NavbarとFooterパーシャルテンプレートを追加したlayouts/base.njkテンプレートは、以下のようになります。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="icon" href="/assets/favicon.jpeg" />
        <link
            rel="stylesheet"
            href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"
            integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
        />
        <link rel="stylesheet" href="/css/global.css" />
        <title>J.'s Portfolio</title>
    </head>
    <body>
        <div>
            {% include "components/navbar.njk" %}
                {{ content | safe }}
            {% include "components/footer.njk" %}
        </div>
    </body>
</html>

レイアウトがページテンプレートに追加されていないため、ここでnpm startコマンドを実行してもレイアウトは表示されません。ページテンプレートを作成して、このレイアウトを追加しましょう。

Eleventyでのページテンプレートの作成方法

srcフォルダ内に、ポートフォリオサイトのトップページとなるindex.njkファイルを作成します。このページはBaseレイアウトを使用します。

---
layout: layouts/base.njk
title: Home
---
<h1> This is the {{title}} Page. </h1>

npm startコマンドを実行すると、静的サイトがhttp://localhost:8080/で起動されます。アクセスすると以下のように表示されます。

レイアウト適用前のページテンプレート
レイアウト適用前のページテンプレート

EleventyでのCSSと画像の使用方法

layouts/base.njkファイルでは、CSSファイルをリンクしてポートフォリオページのスタイルを設定していますが、_siteフォルダ内にCSSファイルがないため、サイトを読み込んでもCSSスタイルが適用されません。

CSSを適用するには、.eleventy.jsファイルでeleventyConfigパラメータを使用します。これにより、EleventyはCSSファイルの位置を把握し、またCSSファイルの変更を監視できます。

srcフォルダ内にcssフォルダを作成し、プロジェクトで使用するすべてのCSSファイルを保存します。この記事では1つのCSSファイル、global.cssを使用します。次にcssフォルダを構成して、フォルダ内のすべてのファイルをプロジェクトに含めます。

eleventyConfig.addPassthroughCopy('src/css');
eleventyConfig.addWatchTarget('src/css');

画像も同様です。ページに画像を追加しても、画像が保存されているフォルダを構成するまではページに表示されません。assetsフォルダを作成してすべての画像を保存し、assetsフォルダを構成します。

eleventyConfig.addPassthroughCopy('src/assets');

構成ファイルは以下のようになります。

module.exports = function (eleventyConfig) {
    eleventyConfig.addPassthroughCopy('src/assets');
    eleventyConfig.addPassthroughCopy('src/css');
    eleventyConfig.addWatchTarget('src/css');

    return {
        dir: {
            input: 'src',
        },
    };
};

npm startコマンドを実行すると、CSSスタイルが適用され、ホームページは以下のように表示されます。

レイアウト適用後のテンプレートの表示
レイアウト適用後のテンプレートの表示

パーシャルテンプレートの作成とホームページへの追加

レイアウトを作成し、ホームページ(index.njk)に追加したら、次にトップページをカスタマイズして、自己紹介やスキル、連絡先などを掲載します。

index.njkテンプレートに直接コードやマークアップを追加しても構いませんが、ここでは、ヒーローエリア、自己紹介、スキル、連絡先用に個別のパーシャルテンプレートを作成します。

Heroパーシャルテンプレート

ナビゲーションバーの下に最初の表示されるヒーローエリアは、訪問者にどのようなサイトなのかを伝えるのが目的です。

<div class="hero-container">
    <img src='assets/profile.jpeg' class="profile-img" alt="Joe's personal headshot" />
    <div class="hero-text">
        <h1>Hey, I'm Joe 👋</h1>
        <p>
            I'm a software developer based in Lagos, Nigeria. I specialize in building (and occasionally designing) exceptional websites, applications, and everything in between.
        </p>
        <div class="social-icons">
            <a href="https://twitter.com/olawanle_joel">
                <i class="fa-brands fa-twitter"></i>
            </a>
            <a href="https://github.com/olawanlejoel">
                <i class="fa-brands fa-github"></i>
            </a>
            <a href="https://www.linkedin.com/in/olawanlejoel/">
                <i class="fa-brands fa-linkedin"></i>
            </a>
        </div>
    </div>
</div>

上のコードでは、簡単な自己紹介とSNSアカウントにリンクしたソーシャルアイコンを記述しています。

Heroパーシャルテンプレートは、以下のように表示されます。

Heroパーシャルテンプレート
Heroパーシャルテンプレート

あとは自由にコンテンツを追加してください。css/globals.cssファイルでスタイルを変更したり、まったく違うバージョンを新規作成したりできます。

Aboutパーシャルテンプレート

Aboutセクションでは、自分に関するより詳しい情報を掲載します。伝えたい情報が大量にある場合は、個別のページにすることも可能です。

<div class="about-container">
    <h2>About Me</h2>
    <div class="flex-about">
        <div class="about-text">
            <p>
                As a developer, I have always been passionate about creating elegant and effective solutions to complex problems. I have a strong foundation in software development, with a focus on web technologies such as HTML, CSS, and JavaScript. I enjoy working on both the front-end and back-end of applications, and I am always looking for ways to optimize performance, improve user experience, and ensure the highest level of code quality.
            </p>
            <p>Throughout my career, I have worked on a wide range of projects, from simple static websites to complex enterprise-level applications. I am experienced in working with a variety of development tools and frameworks, including React, Angular, Vue.js, Node.js, and Laravel. I am always eager to learn and explore new technologies, and I am constantly seeking out opportunities to improve my skills and knowledge.</p>
        </div>
        <div class="about-img">
            <Image src='/assets/about.jpeg' class="profile-img" alt="Joe and animal relaxing and having fun" />
        </div>
    </div>
</div>

このコードでは、自己紹介文とプロフィール画像を記述しており、フロントエンドでは以下のように表示されます。

Aboutパーシャルテンプレート
Aboutパーシャルテンプレート

Skillsパーシャルテンプレート

このセクションには、習得しているスキルや得意とする技術を表示します。

<div class="skills-container">
    <h2>Skills</h2>
    <div class="grid-skills">
        <div class="skill-card html">
            <i class="fa-brands fa-html5 html-icon"></i>
            <p>HTML</p>
        </div>
        <div class="skill-card css">
            <i class="fa-brands fa-css3-alt css-icon"></i>
            <p>CSS</p>
        </div>
        <div class="skill-card js">
            <i class="fa-brands fa-js-square js-icon"></i>
            <p>JavaScript</p>
        </div>
        <div class="skill-card react">
            <i class="fa-brands fa-react react-icon"></i>
            <p>React</p>
        </div>
        <div class="skill-card node">
            <i class="fa-brands fa-node-js node-icon"></i>
            <p>Node</p>
        </div>
        <div class="skill-card python">
            <i class="fa-brands fa-python python-icon"></i>
            <p>Python</p>
        </div>
    </div>
</div>

上のコードは、各スキルのfont-awesomeアイコンと名前のカードを作成します。さらにスタイルを追加し、コードを修正して、見た目をより魅力的にすることも可能です。フロントエンドでは以下のように表示されます。

Skillsパーシャルテンプレート
Skillsパーシャルテンプレート

Contactパーシャルテンプレート

ポートフォリオサイトには、潜在顧客に向けて連絡先を表示することが欠かせません。例えば、メールアドレスは必ず掲載したいところです。

<div class="contact-container">
    <h2>Get In Touch</h2>
    <p>If you want us to work together, have any question or want me to speak at your event, my inbox is always open. Whether just want to say hi, I'll try my best to get back to you! Cheers!</p>
    <a href="mailto:[email protected]" class='cta-btn'>Say Hello</a>
</div>

aタグのメールアドレスは、自分のものに置き換えてください。ボタンをクリックすると、メールアプリケーションが起動し、メッセージを送信できます。

Contactパーシャルテンプレート
Contactパーシャルテンプレート

これで、ホームページ用のすべてのパーシャルテンプレートを作成できました。index.njkファイルに挿入して、ホームページで表示します。

---
layout: layouts/base.njk
title: Home
---
{% include "components/hero.njk" %}
{% include "components/about.njk" %}
{% include "components/skills.njk" %}
{% include "components/contact.njk" %}

npm startコマンドを実行すると、ホームページには追加されたパーシャルテンプレートが表示されます。

Eleventyでのコレクションの使用方法

Eleventyの「コレクション」は、関連するコンテンツをグループ化します。コレクションを使用すると、コンテンツに基づいてページを生成できます。例えば、プロジェクトのblogフォルダに、類似コンテンツ(ブログ記事)のマークダウンファイルが保存されている場合、コレクションを使用してそれらを取得し、すべてのコンテンツの一覧を表示します。またコンテンツの表示を決定するレイアウトも作成可能です。

コレクションは.eleventy.js設定ファイルで定義し、マークダウンやJSONファイルなど、様々なソースからのデータを対象にできます。

今回のポートフォリオサイトでは、srcディレクトリにprojectsディレクトリを作成し、参加したプロジェクトに関するマークダウンコンテンツを保存します。コンテンツには、プロジェクトの詳細、解決した問題、使用した技術、遭遇した課題、得られた教訓が含まれます。

プロジェクト名(quotes-generator.md)でマークダウンファイルを作成し、以下のようなコードを記述します。

---
title: Quotes Generator
description: "Helps you generates quotes from about 1600 quotes written by different authors . Quotes are automatically copied to your clipboards."
gitHubURL: "https://github.com/olawanlejoel/random-quote-generator"
image: "/assets/quotes-banner.jpeg"
---

The quotes generator project is a software tool designed to display random inspirational or thought-provoking quotes to users. This project aims to solve the problem of lack of motivation or inspiration by providing users with a quick and easy way to access inspiring quotes.

### Technologies Used
The technologies used in this project include HTML, CSS, and JavaScript. The application utilizes an API to fetch random quotes and display them to the user.

### Challenges and Lessons Learned
One of the main challenges faced during this project was designing the user interface to be visually appealing and responsive on different devices. The team had to consider various design elements such as font sizes, colors, and layout to create a user-friendly and aesthetically pleasing interface.

Another challenge was handling errors and edge cases such as network connectivity issues or invalid API responses. The team had to implement error handling and fallback mechanisms to ensure that the application would continue to function smoothly under various conditions.

Throughout the project, the team learned valuable lessons about front-end development, such as the importance of clean and efficient code, effective debugging and troubleshooting, and responsive design principles. They also learned the importance of utilizing APIs to access and display data from external sources.

Overall, the quotes generator project was a valuable learning experience that allowed the team to develop their technical and creative skills, and create a useful tool for users looking for daily inspiration or motivation.

注意)スターターテンプレートを使用していれば、すでにファイルは存在しています。使用していなければ、GitHub上のスターターテンプレートのprojectsディレクトリからコピーしてください。

ファイルの一番上にあるFrontmatter(2つの「—」で囲まれた部分)は、テンプレートへの値の挿入に使用されます。

マークダウンファイルはsrcディレクトリ内にあるため、テンプレートとして扱われ、それぞれにHTMLページを生成します。URLは/projects/quotes-generatorのようになります。

レイアウトのないプロジェクト表示
レイアウトのないプロジェクト表示

しかし、Frontmatterにまだレイアウトの値がないため、Eleventyにどのレイアウトを適用すれば良いのかがわかりません。

まずこのコンテンツ用のレイアウトを作成し、次にコレクションを作成して、projectsページに一覧を追加します。

これまでと同様、layoutsフォルダにレイアウトファイル(project.njk)を作成します。このファイルは、デフォルトのHTMLマークアップを使用します。繰り返しを避けるため、base.njkレイアウトを変更して、変更箇所を示すブロックを作成します。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="icon" href="/assets/favicon.jpeg" />
        <link
            rel="stylesheet"
            href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"
            integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
        />
        <link rel="stylesheet" href="/css/global.css" />
        <title>J.'s Portfolio</title>
    </head>
    <body>
        <div>
            {% include "components/navbar.njk" %}
                {% block content %} 
                    {{ content | safe }}
                {% endblock %}
            {% include "components/footer.njk" %}
        </div>
    </body>
</html>

テンプレート内には複数のブロックを配置できるため、ここではブロックに「content」という名前を付けています。これでproject.njkレイアウトを拡張できます。あとはcontentブロックの内容を記述するだけです。

{% extends "layouts/base.njk" %}

{% block content %}
    <div class="project-layout">
        <h2>{{title}}</h2>
        <img src="{{image}}" alt="image" class="banner-img" />
        <a href="{{gitHubURL}}" class="cta-btn pt-btn">
            <div class="small-icons">
                GitHub <i class="fa-brands fa-github"></i>
            </div>
        </a>
        {{ content | safe }}
    </div>
{% endblock %}

上のコードでは、プロジェクトの表示方法を指定しています。FrontmatterからtitleimagegitHubURLを取得し、content変数({{ content | safe }})を使用してその他のコンテンツを追加します。

次に、各プロジェクトのFrontmatterにレイアウトを追加します。

---
layout: layouts/project.njk
title: Quotes Generator
description: "Helps you generates quotes from about 1600 quotes written by different authors . Quotes are automatically copied to your clipboards."
gitHubURL: "https://github.com/olawanlejoel/random-quote-generator"
image: "/assets/quotes-banner.jpeg"
---

…

各プロジェクトのURL(例:/projects/quotes-generator)を再読み込みすると、作成されたレイアウトが使用されます。

レイアウトされたプロジェクト表示
レイアウトされたプロジェクト表示

テンプレートでのコレクションの使用方法

ここまでの作業で、各プロジェクトが指定したレイアウトで美しく表示されるようになりましたが、プロジェクトページにアクセスする手段がありません。続いては、クリックして各プロジェクトページに移動できる、プロジェクト一覧を作成します。ここで登場するのがコレクションです。

コレクションを使用するには、.eleventy.js設定ファイル内にaddCollection()メソッドで定義します。

module.exports = function (eleventyConfig) {
    // …

    eleventyConfig.addCollection('projects', (collection) => {
        return collection.getFilteredByGlob('src/projects/*.md');
    });

    return {
        // ...
    };
};

上のコードでは、addCollection()メソッドを使用してprojectsコレクションを定義しています。addCollection()に渡されたコールバック関数は、getFilteredByGlob()メソッドを使用して、projectsディレクトリ内のすべてのマークダウンファイルを返します。

コレクションを定義したら、コンテンツに基づいたページの生成のためにテンプレートで使用できます。projects.njkページテンプレートを作成して、base.njkレイアウトを使用します。

---
layout: layouts/base.njk
title: Projects
---
<div class="projects-container">
    <h2>Projects</h2>
    <div class="projects-grid">
        {% for project in collections.projects %}
            <div class="project-card">
                <div class="project-header">
                    <i class="fa-regular fa-folder-open folder-icon"></i>
                    <div class="small-icons">
                        <a href={{project.data.gitHubURL}}><i class="fa-brands fa-github"></i></a>
                    </div>
                </div>
                <h3>{{project.data.title}}</h3>
                <p>{{project.data.description}}</p>
                <a href="{{project.url}}" class="cta-btn">Read more</a>
            </div>
        {% endfor %}
    </div>
</div>

上のコードでは、{% for %}ステートメントを使用して、コレクション内のすべてのプロジェクトをループし、それぞれにプロジェクトカードを生成します。

すべての変数は、project.data.[key]を使用して参照できます。例えば、上のコードはプロジェクトのタイトル、説明、GitHubのURLを表示します。project.urlを使用するとプロジェクトのURLにもアクセスできます。

npm startコマンドを実行し、projectsページにアクセスします。複数のプロジェクトを追加していると、以下のようなページが表示されます。

Projectsテンプレートページ
Projectsテンプレートページ

ショートコードの作成方法

ショートコードは、カスタムHTMLタグやJavaScriptの動的な値を定義し、テンプレート全体で再利用できます。例えば、現在の年を生成してウェブサイトに追加するショートコードを定義可能です。

ショートコードは、.eleventy.js設定ファイル内でaddShortcode()メソッドを使用して定義します。以下のコードはyearショートコードを定義する例です。

module.exports = function (eleventyConfig) {
    // ...
    eleventyConfig.addShortcode('year', () => {
        return `${new Date().getFullYear()}`;
    });
    return {
        // ...
    };
};

このショートコードは現在の年を返します。これをプロジェクト内の任意のテンプレートに追加可能です。例えば、ウェブサイトのフッターに年をハードコードする代わりに{% year %}を使用すると、毎年、動的に更新されます。

<hr />
<div class="footer-container">
    <p>© {% year %} Joel's Portfolio</p>
    <div class="social_icons">
        // ...
    </div>
</div>

ページをレンダリングすると、出力のHTMLのpタグ内には、現在の年が含まれます。

Eleventyサイトにテーマを追加する方法

Eleventyサイトにテーマを追加することで、サイトの外観を素早くカスタマイズできます(公式にはスターターと呼ばれる)。多くのウェブサイトが無料でEleventyのテーマを提供しており、公式EleventyスターターJamstackテーマなどがその一例です。

利用するには任意のテーマやスターターを選択し、GitHubリポジトリにアクセスして、ローカルマシンに複製するだけでOKです。プロジェクトの設定やカスタマイズ手順については、必ずドキュメントを参照してください。

npm installを実行して使用するすべてのパッケージをインストールし、npm startコマンドを実行します。アプリケーションには、http://localhost:8080/でアクセスできます。

Eleventyサイトをデプロイする方法

これで、Eleventyを使用して洗練された静的ポートフォリオサイトを作成できました。ただし、ローカルマシンにウェブサイトがあるだけでは十分ではありません。オンラインでホスティングして世界中の人に向けて配信しましょう。

Kinstaでは、Eleventyサイトをはじめとした、静的サイト向けホスティングを提供しています。お好きなGitサービス(BitbucketGitHubGitLab)にコードをプッシュするだけで、Kinstaにデプロイできます。

Gitサービスにファイルをプッシュする前に、プロジェクトのルートに.gitignoreファイルを作成して、Gitが無視するファイルとフォルダを指定することができます。

# dependencies
/node_modules

# run
/_site

GitHubにEleventyサイトをプッシュする

今回はGitHubを使用する例をご紹介します。GitHubにリポジトリを作成し、gitコマンドを使用して、コードをプッシュします。

まずは、ローカルのGitリポジトリを初期化します。ターミナルを開き、プロジェクトのディレクトリに移動して、以下のコマンドを実行します。

git init

次にコードをローカルのGitリポジトリに追加します。

git add .

変更をコミットします。

git commit -m "my first commit"

注意)「my first commit」は、変更点を説明する簡単な文章で置き換えてください。

最後に、次のコマンドを使用してGitHubにコードをプッシュします。

git remote add origin [repository URL]
git push -u origin master

注意)[repository URL]をGitHubリポジトリのURLで置き換えてください。

これでKinstaにデプロイ可能になりました。

EleventyサイトをKinstaにデプロイする

Kinstaへのデプロイはわずか数秒。リポジトリが準備できたら、以下の手順に従って、静的サイトをKinstaにデプロイしてください。

    1. ログインまたはアカウント登録をして、MyKinstaを開く。
    2. GitプロバイダでKinstaを認証する。
    3. 左サイドバーの「静的サイト」を選択し、「サイトを追加」をクリックする。
    4. デプロイしたいリポジトリとブランチを選択する。
    5. サイトに一意の名前を割り当てる。
    6. 6. 以下の形式でビルド設定を行う。
      • ビルドコマンド: npm run build
      • Nodeのバージョン: 18.16.0
      • 公開ディレクトリ: _site
    7. 「サイトを作成」をクリックする。

以上です。数秒後にはサイトがデプロイされ、アクセス可能なURLが表示されます。

静的サイトホスティングだけでなく、アプリケーションホスティングでも静的サイトをデプロイできます。アプリケーションホスティングは柔軟性に優れ、オートスケーリング、Dockerfileを使用したコンテナイメージのセットアップ、リアルタイムと過去のデータを取得できる包括的な分析など、数々の堅牢な機能を提供しています。

まとめ

この記事では、Eleventyを使用して洗練された静的サイトを作成する方法、Eleventyサイトをゼロからカスタマイズする方法、そして美しいポートフォリオサイトを構築する方法をご紹介しました。

個人ブログからポートフォリオサイト、オンラインストアまで、Eleventyを使用すれば、手間を最小限に抑えて、劇的にサイトをレベルアップすることができます。

静的サイトを作成したら、Kinstaで無料でホスティングしませんか?すぐに利用できるEleventyのHello Worldテンプレートもご用意しています。

Eleventyを使用して何かを開発した経験はありますか?Eleventyにまつわる感想や経験を以下のコメント欄でぜひお聞かせください。

Joel Olawanle Kinsta

Kinstaでテクニカルエディターとして働くフロントエンド開発者。オープンソースをこよなく愛する講師でもあり、JavaScriptとそのフレームワークを中心に200件以上の技術記事を執筆している。