LoginSignup
21
19

More than 3 years have passed since last update.

GitLabでHugoブログを簡単に公開する方法

Last updated at Posted at 2016-06-03

最近、GitLabを使い始めていますが、一言で言うと「よい」です。GitLabはGitHubを真似して作られましたが、無料機能が微妙に違います。特に大きいのは以下ですね。

  • プライベートリポジトリを使える

  • GitLab CIが使える

今までCIはリポジトリ管理とは別のサービスで使っていたひとが多いと思います。GitHub+WerckerやGitHub+Travisなど。

しかし、GitLabは例えば、GitLab Pagesをリポジトリ(master)で作り、GitLab CIを使って自動デプロイすると、即座にページを公開できます。今までCIサービスに紐付けして、リポジトリのビルドをしていたので、その辺は随分簡単になっていると思います。

https://gitlab.com/groups/pages

例えば、hugoでページを作りたいなら、以下の手順で公開できます。

$ git clone git@gitlab.com:pages/hugo.git
$ cd hugo
$ rm -rf .git

# 自分のプロジェクト(リポジトリ)にhugoを作成して以下のコマンドを実行
$ git init
$ git remote add origin git@gitlab.com:$USER/hugo.git

# baseurlを自身のものに変更する
$ vim config.toml
baseurl       = "https://$USER.gitlab.io/hugo/"

$ git add .
$ git commit -m "first"
$ git push -u origin master

# ページが出来上がるまで多少待たなくてはいけないかもしれません
$ curl -sL $USER.gitlab.io/hugo

すごく簡単ですね。.gitlab-ciを置いておくと、ソースをプッシュする度にページがビルドされ更新されます。

ここで、$user.gitlab.ioなどのプロジェクト(リポジトリ)名にすると、アドレスがトップになり、それ以外なら$user.gitlab.io/repoという形になります。

このような関係からこちらにあるサイトジェネレーターを使ってページを作成する場合、使用するアドレスによってはソースの変更が必要になります。

例えば、Octopressで$user.gitlab.ioという形でページを作るには、以下のリポジトリを参考に/octopressを削除します。ちなみに、このリポジトリをGitLabの$user.gitlab.ioリポジトリに使うと、何もしなくてもそのままページを表示できるようになっています。ただ、_config.ymlのURLはユーザーのものに変更しないといけませんが。

公式は$user.gitlab.io/octopressという形を予定しているために、コードを変更しないと適切に表示されません。具体的には、/octopressという指定をコードから削除する必要があります。トップではなく、リポジトリ名を使う場合は、/octopressをリポジトリ名に置き換える必要があります。

もちろん、グループも使えますので、$userのところは、既にGitLabで取得されていないアカウントIDでないかぎり変更可能です。

特にCIとの連携が機能すると思います。このことは、単純なWebサイト作成手順を見ても明らかです。

Hugoのアーカイブページを作成する

Hugoに全記事一覧を分かりやすく表示するページを作成します。以下の記事でだいたいわかると思います。

自分の場合は、以下の様なレイアウト。

layouts/archive/single.html
{{ partial "head" . }}
{{ partial "header" . }}
<div id="container">
   <div class="outer">
        <div id="blog-archives" class="category">
          {{ .Content }}
          {{ range (where .Site.Pages "Type" "post") }}
            <h1>
        <time datetime="{{ .Date }}" itemprop="datePublished">{{ .Date.Format .Site.Params.date_format }}</time>
                <a href="{{ .Permalink }}" title="{{ .Title }}">{{ .Title }}</a>
            </h1>
          {{ end }}
        </div>
    </div>
</div>
{{ partial "footer" . }}
</body>
</html>

あまりカスタマイズしていません。

Hugoの検索システム

Hugoの検索システムを構築する方法です。

大体は下記のコードのとおりです。具体的にGrunt.jsLunr.jsでHugo用に構築します。

自分の場合の構築方法です。書いてあるとおりだとconfigparmalinkを設定しない場合の出力が得られますが、設定している場合は使えません。したがって、急遽無理やりShellScriptで書き直します。これはGruntfile.jsを直せばいいのですが、正直、面倒くさかった...。

#!/bin/zsh
d=${0:a:h:h}
# backup
h=${0:a:h}
if cat $j|jq . ;then
    cp $j $h
fi
h=$h/PagesIndex.json
j=$d/static/bower_components/lunr.js/PagesIndex.json
t=`cat $j |jq '.[]'|sed -e 's#/post##g'`
a=`cat $j | sed -e 's#/post##g'`
echo $a >! $j
t=`echo $t|jq -r '.href'|cut -d - -f 1-4`

for (( i=1;i<=`echo "$t"|wc -l`;i++ ))
do
    f=`echo "$t"|awk "NR==$i"`
    c=`echo $f|tr '-' '/'`
    sed -i "" "s#${f}#${c}#g" $j
done

cat $j

diff $j $h

とりあえず記事にあるGrntfile.jsを適時修正し作成し、ビルド後にスクリプトを実行するという手順。

出力ファイルは/bower_components/lunr.js/PagesIndex.jsonに置くこととします。

layouts/partials/widgets/search.html
<div class="widget-wrap">
<input id="search" type="text" placeholder="search">
<ul id="results">
</ul>
<script type="text/javascript" src="/js/search.js"></script>
<script type="text/javascript" src="/bower_components/lunr.js/lunr.min.js"></script>
</div>
js/search.html
var lunrIndex,
    $results,
    pagesIndex;

// Initialize lunrjs using our generated index file
function initLunr() {
    // First retrieve the index file
    $.getJSON("/bower_components/lunr.js/PagesIndex.json")
        .done(function(index) {
            pagesIndex = index;
            console.log("index:", pagesIndex);

            // Set up lunrjs by declaring the fields we use
            // Also provide their boost level for the ranking
            lunrIndex = lunr(function() {
                this.field("title", {
                    boost: 10
                });
                this.field("tags", {
                    boost: 5
                });
                this.field("content");

                // ref is the result item identifier (I chose the page URL)
                this.ref("href");
            });

            // Feed lunr with each file and let lunr actually index them
            pagesIndex.forEach(function(page) {
                lunrIndex.add(page);
            });
        })
        .fail(function(jqxhr, textStatus, error) {
            var err = textStatus + ", " + error;
            console.error("Error getting Hugo index flie:", err);
        });
}

// Nothing crazy here, just hook up a listener on the input field
function initUI() {
    $results = $("#results");
    $("#search").keyup(function() {
        $results.empty();

        // Only trigger a search when 2 chars. at least have been provided
        var query = $(this).val();
        if (query.length < 2) {
            return;
        }

        var results = search(query);

        renderResults(results);
    });
}

/**
 * Trigger a search in lunr and transform the result
 *
 * @param  {String} query
 * @return {Array}  results
 */
function search(query) {
    // Find the item in our index corresponding to the lunr one to have more info
    // Lunr result: 
    //  {ref: "/section/page1", score: 0.2725657778206127}
    // Our result:
    //  {title:"Page1", href:"/section/page1", ...}
    return lunrIndex.search(query).map(function(result) {
            return pagesIndex.filter(function(page) {
                return page.href === result.ref;
            })[0];
        });
}

/**
 * Display the 10 first results
 *
 * @param  {Array} results to display
 */
function renderResults(results) {
    if (!results.length) {
        return;
    }

    // Only show the ten first results
    results.slice(0, 10).forEach(function(result) {
        var $result = $("<li>");
        $result.append($("<a>", {
            href: result.href,
            text: "» " + result.title
        }));
        $results.append($result);
    });
}

// Let's get started
initLunr();

$(document).ready(function() {
    initUI();
});

これで検索システムの完成です。Hugo Buildで同時にPagesIndexを作成するようにしておけばOKです。

21
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
19