Help us understand the problem. What is going on with this article?

HUGOで作れるCMSっぽいパーツ:関連記事・目次・JSON-LDなど

More than 3 years have passed since last update.

超爆速でコンパイルができる、Go言語製の静的サイトジェネレーターHUGO

当然、HUGOでは静的HTMLサイトしか作ることができない。しかし、テンプレート機能をうまく作ればWordPressにも負けないようなパーツが結構作れてしまう。この記事では、HUGOで構築した自分のブログを例に、いくつかのCMSっぽいパーツ見本集をまとめる。

テンプレート見本

  • バージョン0.16で動作確認
    • Hugo Static Site Generator v0.16 BuildDate: 2016-06-06T21:37:59+09:00
  • テンプレート機能の見本なので、CSSについては言及しない

HUGOのページの種類とVariablesの関係

HUGOでは、ページの種類によってテンプレートから参照できる変数に違いがある。

名称 説明
Node Variables ホームページやタグ一覧ページなど、一覧系ページでしか参照できない変数
Page Variables Markdownからコンパイルされた記事ページでしか参照できない変数
Site Variables サイトのどのページからも参照できる変数

Node Variablesに分類される変数を記事ページからは使用できないし、Page Variablesに分類されているものを一覧系のページで呼び出すこともできない。(ビルド時にエラーが出る)

このため、サイドバーなどのサイト全体で使うパーツに対しては、どの場所からも参照できるSite Variablesで完結させる必要がある。

各見本の冒頭部には、そのテンプレートが依存する変数がどれに分類されるかを記載する。

アイキャッチとタグ付きの新着順記事一覧

[Node Variables]

この例では、記事のMarkdownへアイキャッチ画像用のURLをfront-matterのimageプロパティを記述し、項目が存在する場合はHTMLに出力するようにしている。

存在の有無でclassも変化する為、レイアウトをそれぞれ適当なものに変えることができる。

ちなみに、.Summaryconfig.tomlHasCJKLanguage = trueを設定しないとおかしな表示になってしまうので、日本語のブログを作るときは必ず設定しておこう。

新着記事の一覧.png

HTML

  • ページネーションなしで全件出力
テーマ/layouts/index.html
<!-- article-list -->
<section class="article-list">
  <h2 class="article-list__head" itemprop="name">記事一覧</h2>
  <ol class="article-list__list">
    {{ range .Data.Pages.ByDate.Reverse }}
      {{ .Render "li" }}
    {{ end }}
  </ol>
</section>
<!-- /article-list -->
テーマ/layouts/_default/li.html
<li class="article-list__item">
  <!-- article-sneak -->
  <article class="article-sneak {{ if .Params.image }}article-sneak--thumb{{ end }}">
    <div class="article-sneak__link" onclick="location.href='{{ .RelPermalink | safeJS }}'">
      <div class="article-sneak__text article-sneak__wrapper">
        <div class="article-sneak__inner">
          <p class="article-sneak__date">
            <a href="{{ .RelPermalink }}"><time datetime="{{ .Date.Format " 2006-01-02T15:04:05Z07:00" | safeHTML }}">{{ .Date.Format "2006.01.02" }}</time></a>
          </p>
          <h3 class="article-sneak__head">
            <a href="{{ .RelPermalink }}">{{ .Title }}</a>
          </h3>
          {{ if .Params.tags }}
          <dl class="article-sneak__tags">
            <dt><i class="icon icon-tag"></i></dt>
            <dd>
              {{ range .Params.categories }}
              <a href="/categories/{{ . | urlize }}/">{{ . }}</a>
              {{ end }}
            </dd>
            <dd>
              {{ range .Params.tags }}
              <a href="/tags/{{ . | urlize }}/">{{ . }}</a>
              {{ end }}
            </dd>
          </dl>
          {{ end }}
          <p class="article-sneak__body"><a href="{{ .RelPermalink }}">{{ .Summary }}</a></p>
        </div>
      </div>
      {{ if and (.Params.image) (ne .Params.image "") }}
      <div class="article-sneak__figure article-sneak__wrapper">
        <div class="article-sneak__inner">
          <a href="{{ .RelPermalink }}"><p class="article-sneak__thumb" style="background-image: url({{ .Params.image }});">
            <img style="display:none" src="{{ .Params.image }}" alt=""/>
          </p></a>
        </div>
      </div>
      {{ end }}
    </div>
  </article>
  <!-- /article-sneak -->
</li>

Markdown

アイキャッチ画像がある場合はimageプロパティにパスを記載する。

+++
image = "/blog/makeowndigitalbook/stackroom.png"
+++

なお.Summaryの内容を制御する方法はこちらの記事が詳しい。

Hugoにおける記事要約の仕組み - Qiita

ページネーション付の記事一覧と操作UI

[Node Variables]

前項とほぼ一緒だが、ボタン部分に加えて、一覧の抽出条件の書き方が違ってくる。

HTML(一覧)

この書き方だと、出力される記事件数はデフォルトの件数となる。ページネーションのデフォルト件数はconfig.tomlに設定できる。liパーシャルの中身は前項ママでそのまま使えるので省略する。

テーマ/layouts/_default/list.html
<!-- article-list -->
<section class="article-list ">
  <h2 class="article-list__head">{{ .Title }}の記事一覧</h2>
  <ul class="article-list__list">
    {{ range .Paginator.Pages }}
      {{ .Render "li" }}
    {{ end }}
  </ul>
  {{ partial "pagination-nav.html" . }}
</section>
<!-- /article-list -->

config.toml

1ページあたり20件の表示としたい場合はこのように書く。

paginate = 20

HTML(ボタン部分)

スクリーンショット 2016-06-08 12.05.36.png

ページネーションの操作UIは、次のように実装した。

<nav role="pagination" class="pagination-nav">

  <p class="pagination-nav__btn pagination-nav__btn--prev">
    <a class="pagination-nav__item pagination-nav__item--link" {{ if .Paginator.HasPrev }} href="{{.Paginator.Prev.URL}}" {{ end }}>
      <i class="icon icon-arrow-left"></i>前のページへ
    </a>
  </p>

  <p class="pagination-nav__btn pagination-nav__btn--summary">
    <span class="pagination-nav__item">
      {{.Paginator.PageNumber}}/{{.Paginator.TotalPages}}
    </span>
  </p>

  <p class="pagination-nav__btn pagination-nav__btn--next">
    <a class="pagination-nav__item pagination-nav__item--link" {{ if .Paginator.HasNext }} href="{{.Paginator.Next.URL}}" {{ end }}>
      次のページへ<i class="icon icon-arrow-right"></i>
    </a>
  </p>
</nav>

押せない時に薄くなる表現はCSSで実装している。

本文の途中に挿入する目次

[Page Variables]

標準の機能では記事の内部に目次を混ぜることはできない。

そこで、あらかじめ本文中に空のHTML構造を挿入しておき、目次のパーツをJavaScriptで移動させる。これで、外観上は目次が途中に挿入されているように見える。

本文の途中の目次.png

HTML

テーマ/layouts/_default/single.html
<!-- single.htmlの一部 -->
<section>
  <div class="body">
    {{ if eq .Params.usetoc true }}
      {{ partial "toc.html" . }}
    {{ end }}
    {{ .Content }}
  </div>
</section>
テーマ/layouts/partials/toc.html
<section class="js-toc">
  <h2>目次</h2>
  <div class="toc">
  {{ .TableOfContents }}
  </div>
</section>

JavaScript

var $tocPlace = $('#js-toc-place');
if ($tocPlace.length === 1) {
  $('.js-toc').appendTo($tocPlace);
}

Markdown

front-matter内でusetocフラグを使い、必要な記事にだけ目次を挿入できるようにしている。

+++
usetoc = true
+++
それでもメリットはかなり大きい。

<!-- この部分に目次を挿入 -->
<div id="js-toc-place"></div>

## 必要機材

本を自炊するためにはどうしても機材が必要になる。

独自デザインの共有ボタン

[Page Variables]

facebook, twitter, はてブ, メール送信に対応したリンク要素を生成する。本来の用途と異なるかもしれないが、safeJSフィルターが良好に機能した。

SNS共有ボタン.png

<!-- content-footer -->
<div class="content-footer ">
  <p class="content-footer__text">最後までお読みいただきありがとうございます!<i class="icon icon-share"></i></p>
  <ul class="content-footer__sns-list">
    <li class="content-footer__sns-item ">
      <p class="button button--sns button--sns--fb">
        <a class="button__link" href="https://www.facebook.com/sharer/sharer.php?u={{ .Permalink | safeJS }}"><i class="icon icon-facebook"></i>Facebookで共有</a>
      </p>
    </li>
    <li class="content-footer__sns-item ">
      <p class="button button--sns button--sns--tw">
        <a class="button__link" href="http://twitter.com/intent/tweet?text={{ .Title | safeJS }}%20%7C%20{{ .Site.Title }}%20{{ .Permalink | safeJS }}%20%40{{ .Site.Params.twitter }}"><i class="icon icon-twitter"></i>Twitterで共有</a>
      </p>
    </li>
    <li class="content-footer__sns-item ">
      <p class="button button--sns button--sns--hb">
        <a class="button__link" href="http://b.hatena.ne.jp/entry/{{ .Permalink | safeJS }}"><i class="icon icon-hatebu"></i>はてなブックマークで共有</a>
      </p>
    </li>
    <li class="content-footer__sns-item">
      <p class="button button--sns button--sns--mail">
        <a class="button__link" href="mailto:?subject={{ .Title }}&amp;body={{ .Permalink | safeURL }}">メールで共有</a>
      </p>
    </li>
  </ul>
</div>
<!-- /content-footer -->

関連記事

[Page Variables]

表示中の記事に含まれるタグを持つ、自分自身を含まない他の記事の一覧を出力する。

関連記事の一覧.png

HTML

残念ながら、この書き方だと関連記事が0件の時にもh2の見出しが出力されてしまう。色々試したものの、テンプレートのレベルでは解消できなかった。もし解消できたらここへ追記する。

<!-- related-articles -->
{{ if .Params.tags }}
<nav class="related-articles js-related-articles">
  <h2 class="content-footer__text">関連記事</h2>
  <ul class="related-articles__links">
   {{ $currentTitle := .Title }}
    {{ $page_link := .RelPermalink }}
    {{ $tags := .Params.tags }}
    {{ range .Site.Pages }}
    {{ $page := . }}
    {{ $has_common_tags := intersect $tags .Params.tags | len | lt 0 }}
    {{ if and $has_common_tags (ne $page_link $page.RelPermalink) }}
    <li class="related-articles__item js-items">
      <article class="related-article">
        <a class="related-article__link" href="{{ $page.Permalink }}">
          <p class="related-article__stock">{{ $page.Date.Format "2006.01.02." }}</p>
          <h3 class="related-article__title">{{ $page.Title }}</h3>
          <p class="related-article__tags">
            {{ range $page.Params.tags }}
            <span class="related-article__tag">
            {{ . }}
            </span>
            {{ end }} </p>
        </a>
      </article>
    </li>
    {{ end }}
    {{ end }}
  </ul>
</nav>
{{ end }}
<!-- /related-articles -->

JavaScript

……こういった訳で、見出しはJavaScript側で除去する実装。

function removeEmptyRelated() {
    let $target = $('.js-related-articles');
    let items = $target.find('.js-items');

    if (items.length !== 0) {
      return false;
    }

    $target.remove();
  }

前の記事/次の記事へのナビゲーション

[Page Variables]

同一セクションに限定し、前後の投稿がある場合はそれを出力する。

前後の記事へのナビゲーション.png

<!-- content-nav -->
<nav class="content-nav ">
  <ol class="content-nav__links">
    {{ if .PrevInSection }}
    <li class="content-nav__item">
      <p class="content-nav__label">前の投稿</p>
      <p class="button button--article-nav">
        <a class="button__link" href="{{.PrevInSection.RelPermalink}}"><i class="icon icon-arrow-left"></i>{{ .PrevInSection.Title }}</a>
      </p>
    </li>
    {{ end }}
    {{ if .NextInSection }}
    <li class="content-nav__item">
      <p class="content-nav__label">次の投稿</p>
      <p class="button button--article-nav">
        <a class="button__link" href="{{.NextInSection.RelPermalink}}"><i class="icon icon-arrow-right"></i>{{ .NextInSection.Title }}</a>
      </p>
    </li>
    {{ end }}
  </ol>
  <div class="content-nav__menu">
    <p class="button button--article-nav button--article-nav--menu">
      <a class="button__link" href="/"><i class="icon icon-menu"></i>記事一覧へ戻る</a>
    </p>
  </div>
</nav><!-- /content-nav -->

特別な記事だけを抽出して一覧

[Site Variables]

pickupフラグがtrueの記事だけを限定して抽出してアイキャッチ画像を並べる。
あらかじめ各記事のfront-matterにpickuptypeimageを記述しておく。

固定された記事の表示枠.png

HTML

  • 「project」タイプで「pickup」パラメーターがtrueの記事を時系列の逆順に3件まで表示
  • 「docs」タイプで「pickup」パラメーターがtrueの記事を時系列順に2件まで表示
<!-- gallery-sneak -->
<div class="gallery-sneak site-hero--footer">
  <div class="gallery-sneak__inner">
    <ul class="gallery-sneak__list">
      {{ range first 3 (where (where .Site.Pages.Reverse ".Params.pickup" "true" ) "Type" "project") }}
      <li class="gallery-sneak__item">
        <a href="{{ .RelPermalink }}" style="background-image: url({{ .Params.image }});">
          <img src="{{ .Params.image }}" alt=""/>
        </a>
      </li>
      {{ end }}
      {{ range first 2 (where (where .Site.Pages ".Params.pickup" "true" ) "Type" "docs") }}
      <li class="gallery-sneak__item">
        <a href="{{ .RelPermalink }}" style="background-image: url({{ .Params.image }});">
          <img src="{{ .Params.image }}" alt=""/>
        </a>
      </li>
      {{ end }}
    </ul>
  </div>
</div>
<!-- /gallery-sneak -->

Markdown

上記の抽出条件にマッチさせるには、front-matter内へ次を記載する。

+++
type = "docs"
pickup = "true"
image = "/path/to/image.png"
+++

メタ情報

[汎用]

Facebook, Twitter cardに対応したメタタグ。OGPの内容にこだわると結構条件分岐が増える。パーシャル化して運用した方がよいだろう。

HTML

<meta charset="UTF-8">
<!--
トップページだけ特別ルールにする
-->
{{ if .IsHome }}
<title>{{ .Site.Title }}</title>
{{ else }}
<title>{{ .Title }} | {{ .Site.Title }}</title>
{{ end }}
<meta name="generator" content="{{ .Hugo.Generator }}">
<meta name="author" content="{{ .Site.Author.name }}">
<meta property="og:locale" content="{{ .Site.Params.localeOgp }}">
<meta property="fb:app_id" content="{{ .Site.Params.fbAppId }}">
<meta property="og:title" content="{{ .Title }}">
<meta property="og:url" content="{{ .Permalink }}">
<meta property="og:site_name" content="{{ .Site.Title }}">
<!--
1. `.Description`がある場合はそれを使用
2. 「1」が存在せず、nodeの場合は`.Summary`を使用
3. 「1」「2」が存在しない場合は共通の説明文を使用
-->
{{ if .Description }}
<meta name="description" content="{{ .Description }}">
<meta property="og:description" content="{{ .Description }}">
<meta name="twitter:description" content="{{ .Description }}">
{{ else }}
{{ if .IsPage }}
<meta name="description" content="{{ .Summary }}...">
<meta property="og:description" content="{{ .Summary }}...">
<meta name="twitter:description" content="{{ .Summary }}...">
{{ else }}
{{ if .IsHome }}
<meta name="description" content="{{ .Site.Params.description }}">
<meta property="og:description" content="{{ .Site.Params.description }}">
<meta name="twitter:description" content="{{ .Site.Params.description }}">
{{ else }}
<!-- 同じdescriptionのページが重複することを避ける -->
<meta name="description" content="{{ .Title }}に関連する記事の一覧です。{{ .Site.Params.description }}">
<meta property="og:description" content="{{ .Title }}に関連する記事の一覧です。{{ .Site.Params.description }}">
<meta name="twitter:description" content="{{ .Title }}に関連する記事の一覧です。{{ .Site.Params.description }}">
{{ end }}
{{ end }}
{{ end }}
<!--
記事にアイキャッチ画像がある場合はそれをOGP:imageに指定する。
存在しない場合はサイトデフォルトの画像を指定する。
-->
{{ if and (.Params.image) (ne .Params.image "") }}
<meta property="og:image" content="{{ .Params.image | absURL }}">
<meta property="twitter:image" content="{{ .Params.image | absURL }}">
{{ else }}
<meta property="og:image" content="{{ .Site.Params.ogpimage | absURL }}">
<meta property="twitter:image" content="{{ .Site.Params.ogpimage | absURL }}">
{{ end }}
<!--
記事ページはog:typeをarticleにする。公開日時、タグもキーワードとして出力
-->
{{ if .IsPage }}
<meta property="og:type" content="article">
<meta property="og:article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}">
{{ range .Params.tags }}<meta property="og:article:tag" content="{{ . }}" />{{ end }}
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@{{ .Site.Params.twitter }}">
<meta name="twitter:creator" content="@{{ .Site.Params.twitter }}">
<meta name="twitter:title" content="{{ .Title }}">
<meta name="twitter:url" content="{{ .Permalink }}">
{{ else }}
<meta property="og:type" content="website">
{{ end }}
<!--
  トップでなければホームページへのリンクを出力
-->
{{ if ne .IsHome true }}
<link rel="index" href="/"/>
{{ end }}
<!--
  ページネーションがある場合は、next/prevを出力
-->
{{ if .IsNode }}
{{ if .Paginator.HasPrev }}
<link rel="prev" href="{{.Paginator.Prev.URL}}"/>
{{ end }}
{{ if .Paginator.HasNext }}
<link rel="next" href="{{.Paginator.Next.URL}}"/>
{{ end }}
{{ end }}
<!--
  前後の記事がある場合は、next/prevを出力
-->
{{ if .IsPage }}
{{if .PrevInSection}}<link rel="prev" href="{{ .PrevInSection.RelPermalink }}">{{end}}
{{if .NextInSection}}<link rel="next" href="{{ .NextInSection.RelPermalink }}">{{end}}
{{ end }}
<!-- HUGOが生成するAtomフィード -->
<link href="{{ .Site.RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Site.Title }}">

意味情報(JSON-LD)

バージョン0.16からjsonifyフィルタや、記事からプレーンテキストだけを取得できる.Plain変数が追加され、JSON-LDのテンプレートがかなり作成しやすくなった。

記事ページのJSON-LD

[Page Variables]

記事ページをBlogPostingとしてマークアップするためのJSON-LDを記載する。

注意が必要な点として、BlogPostingタイプでは、記事の画像(image)、著者(author)、出版元(publisher)フィールドが必須となっている。しかも、上の3つはそれぞれImageObjectPersonOrganizationのタイプでなければならない。

そのため、画像のない記事には、あらかじめ適当なデフォルト画像をあてがう必要がある。OGP対応のためのデフォルト画像を流用するのが適当だろう。

さらにImageObjectタイプはwidthheightの値が必須となるので、画像の縦横ピクセル値をFront-matterへ記載する必要もある。

テーマ/layouts/partial/json-ld-single.html
<!-- ブログ記事の情報 -->
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BlogPosting",
  "@id": "{{ .Permalink }}",
  "name": {{ .Title | jsonify }},
  "headline": {{ .Title | jsonify }},
  "description": {{ .Summary | jsonify }},
  "dateModified": "{{ .Lastmod.Format "2006-01-02" }}",
  "datePublished": "{{ .Date.Format "2006-01-02" }}",
  "mainEntityOfPage": "{{ .Permalink }}",
  "url": "{{ .Permalink }}",
  {{ /* 字数 */ }}
  "wordCount": "{{ .WordCount }}",
  {{ /* プレーンテキストの本文 */ }}
  "articleBody": {{ .Plain | jsonify }},
  "articleSection": {{ .Section | jsonify }},
  {{ /* カテゴリをジャンルとして使用 */ }}
{{if .Params.categories }}  "genre": "{{ range .Params.categories }}{{ . }}{{ end }}",{{ end }}
  {{ /* タグをキーワードとして使用 */ }}
{{if .Params.tags }}  "keywords": "{{ range .Params.tags }}{{ . }}{{ end }}",{{ end }}
  "inLanguage": "{{ .Site.LanguageCode }}",
  "image": {
    "@type": "ImageObject",
    {{ if and (.Params.image) (ne .Params.image "") }}
    "url": "{{ .Params.image | absURL }}",
    "width": "{{ .Params.imagewidth  }}",
    "height": "{{ .Params.imageheight }}"
    {{ else }}
    "@id": "{{ .Permalink }}#ogp"
    {{ end }}
  },
  "author": { "@id": "{{ .Permalink }}#author" },
  "publisher": { "@id": "{{ .Permalink }}#org" }
}
</script>

<!-- 著者の情報 -->
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Person",
  "@id": "{{ .Permalink }}#author",
  "name": "{{ .Site.Author.author }}",
  {{ /* この人物の説明 */ }}
  "description": {{ .Site.Author.profile | jsonify }},
  {{ /* プロフィール画像 */ }}
  "image": "{{ .Site.Author.image | absURL }}"
}
</script>

<!-- 記事にimageが設定されていない場合のデフォルト画像。OGPのデフォルト画像を流用している -->
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "ImageObject",
  "@id": "{{ .Permalink }}#ogp",
  "url": "{{ "/images/ogp.png" | absURL }}",
  "width": "{{ .Site.Params.ogpimagewidth }}",
  "height": "{{ .Site.Params.ogpimageheight }}"
}
</script>

<!-- 出版元となる組織。個人ならサイト名とかにしておけば妥当か -->
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Organization",
  "@id": "{{ .Permalink }}#org",
  "name": "{{ .Site.Title }}",
  {{ /* logoは必須。ここにもOGP画像を使用 */ }}
  "logo": { "@id": "{{ .Permalink }}#ogp" }
}
</script>

Markdown

上のテンプレートを使うには、front-matterに次の設定が必要となる。

# メイン画像へのパス
image = "/path/to/image.png"
# メイン画像のサイズ(メイン画像がない場合は不要)
imagewidth = 1024
imageheight = 768

config.toml

前項のメタ情報・意味情報を使うための設定ファイルサンプル。

サイト全体で使用するメタ情報は、config.tomlの[params]下へ自由に増やせる。テンプレートからは.Site.Params.xxxでアクセスできる。

baseurl = "http://hogehoge.com"
languageCode = "ja"
title = "サイト名を入れる"
HasCJKLanguage = true

[author]
  author = "名前"
  profile = "自己紹介"
  image = "path/to/profile/image.png"

[params]
  localeOgp = "ja"
  description = "トップページ用の説明文"
  fbAppId = "facebookのAppIDを入れる"
  ogpimage = "images/ogp.png"
  ogpimagewidth = "1200"
  opgimageheight = "620"
  twitter = "twitterCard用のユーザー名を入れる"

記事冒頭だけを配信するRSS/Atomフィード

[Site Variables]

デフォルトのテンプレートだと記事の全文が配信されてしまう。新着20件の.Summary部分だけが出力されるテンプレートにするにはlayouts/_default/rss.xmlを作成して以下の様にする。

XML

テーマ/layouts/_default/rss.xml
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
    <link>{{ .Permalink }}</link>
    <description>Recent content {{ with .Title }}in {{.}} {{ end }}on {{ .Site.Title }}</description>
    <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
    <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
    <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
    <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
    <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
    <atom:link href="{{.URL}}" rel="self" type="application/rss+xml"/>
    {{ range first 20 .Data.Pages }}
    <item>
      <title>{{ .Title }}</title>
      <link>{{ .Permalink }}</link>
      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
      {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
      <guid>{{ .Permalink }}</guid>
      <description>
        <p>{{ .Summary }}...</p>
        <p><a href="{{ .Permalink }}">Read More</a></p>
      </description>
    </item>
    {{ end }}
  </channel>
</rss>

参考サイト

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした