GIF画像をアップロードできない

メディア機能などで、PNGやJPEGはアップロードできるが、GIF画像がアップロードできない現象が起こる場合があります。

これは、画像エンジンに GD を使用していて、WebP画像 をサポートしている場合に、サーバー環境によって、GIF画像からWebP画像が生成できずにエラーが出てしまうためとなります。

対策1: GDではなく、ImageMagick に変更する

対策の1つとして、画像エンジンを GD ではなく、ImageMagick に変更する方法があります。(デフォルトは ImageMagick
private/config.system.yaml に以下の記述をすることで、画像エンジンを GDからImageMagickに変更できます。

image_magick : on

注意点として、サーバー環境によっては、ImageMagickを利用できない環境もあります。利用できない環境では、上記設定をしても画像エンジンは GD のままとなります。

対策2:WebP画像サポートをやめる

もう一つの対策は、WebP画像サポートをやめることです。 private/config.system.yaml に以下記述をすることで、WebP画像の生成をやめることができます。

webp_support: off

エントリーなどの編集作業を行なっても、古い情報が表示される場合がある

キャッシュの影響が考えられます。キャッシュドライバーに「APCu」を選択している場合、サーバー環境によってはPHPプロセス毎にキャッシュが確保されてしまい、古いキャッシュが返ってきてしまう問題を確認しています。たとえば、XSERVERの「Xアクセラレーター Ver. 1」や「Xアクセラレータオフ」 を選択している場合(Xアクセラレーター Ver. 2 は大丈夫です)、この環境となります。

このような環境の場合、「.env」ファイルを修正して「APCu」ドライバーを使わないように修正をお願いします。

# テンプレートのキャッシュをするドライバーを選択します
CACHE_TEMPLATE_DRIVER=file
CACHE_TEMPLATE_NAMESPACE=template
CACHE_TEMPLATE_LIFETIME=2678400

# フィールド情報のキャッシュをするドライバーを選択します
CACHE_FIELD_DRIVER=file
CACHE_FIELD_NAMESPACE=field
CACHE_FIELD_LIFETIME=86400

# 一時キャッシュで利用するドライバーを選択します
CACHE_TEMP_DRIVER=memory
CACHE_TEMP_NAMESPACE=temp
CACHE_TEMP_LIFETIME=10800

静的HTMLサイトからCMSのテーマを作ってみよう 4「子ブログ編」


はじめに

「静的HTMLサイトからCMSのテーマを作ってみよう」では、静的HTMLファイルをa-blog cmsで利用できるようなテンプレートファイルに編集し、最終的には1つのオリジナルテーマを作成していきます。

このコンテンツについては

を完了した後にご覧ください。

またチュートリアルの実践環境として、本編ではローカルサーバー http://localhost を使用して説明しておりますが、以下のフォームから実際に作業をするサーバーのURLを入れていただく事で、文中のテキストを希望のURLに書き換えることができます。ぜひご活用ください。

子ブログとは

a-blog cms のブログは、階層化されたブログシステムになり、親は子のブログを管理する権限を持たせる事ができ、子は親にアクセスする権限はありません。

子ブログと書くことが多いですが、子の下階層である孫ブログのように、さらに下階層や、その下にもブログを作ることは可能です。

http://localhost/ko-blog/mago-blog/cagegory/ko-cagtegory/entry.html

このように URL は表現されます。

サイトの設計側はブログなのか、カテゴリーなのか分かっていますが、サイトを閲覧している人は、どちらもディレクトリーであり、区別がつくものではありません。

カテゴリーを子ブログに変更する

まずは「お知らせ」の子ブログを作成していきます。現在 news というコードはお知らせカテゴリーで使われており、新しく作成する子ブログのコードには使用することができません。そのため、まずはお知らせのカテゴリーコード news を変更します。

管理ページより カテゴリー設定画面 にアクセスして、「news」を「news-delete」と変更してください。 エントリーを移設後は削除予定です。



次に ブログ管理の画面 より、右上にある緑色の 子ブログを作成 ボタンをクリックして、新規ブログ作成画面を表示させます。



名前を「お知らせ」とし、コードネームを「news」に設定ください。



以上でお知らせブログが作成できました。URLは http://localhost/news/ になります。 ブログ管理の画面でブログ間の移動は可能ですが、管理画面の左上にあるブログ名をクリックすると、親ブログと子ブログを切り替えることも可能です。



継承したテーマを作成&設定する

新しく作成した「お知らせ」の子ブログには、初期設定として blog テーマが設定されています。このテーマを変更して、親ブログで利用されている sample のような、お知らせブログ専用のテーマを作成し設定します。



この場合、sample と似たデザインや機能を持つテーマを作ることになり、その事を「テーマの継承」と呼びます。今回、お知らせの子ブログのテーマは、sample を継承した子テーマ news@sample という名前で用意します。

この継承機能を利用すると、 news@sample に無いファイルは sample を利用することになり、お知らせ子ブログ側のテーマのテンプレート数を減らし、メンテナンス時も1つ修正すればいいことになります。

/themes/news@sample を作成してください。



その後、お知らせブログのテーマ設定 より、テーマディレクトリ名を「news@sample」を選択し、テンプレート設定の テンプレート選択ファイル(template.yaml)の値を優先する のチェックを外します。

template.yaml が利用されないので、下部のテンプレートファイル指定が有効になりますので、以下のように設定します。 今回の子ブログ「お知らせ」では、特別なトップページを用意せず、一覧ページと同様のトップページとしますので、_top.html ではなく index.html をトップページのテンプレートとして指定しています。

種類ファイル名今回の作業
トップページindex.html修正
一覧ページindex.html
詳細ページ_entry.html修正
エラーページ(404 Not Found)404.html
管理ページadmin.html
エントリー編集ページ_entry.html修正
ユニット追加ページ_entry.html修正
ログインページlogin.html


エントリーを移行する

親ブログ内にある「お知らせ」のエントリーをまとめて子ブログ側に移動します。親ブログのエントリー管理画面から絞り込み機能を利用して、「お知らせ」エントリーを一覧表示してください。

  1. カテゴリーを選択
  2. 検索ボタンをクリック
  3. 一番上のチェックボックスをクリック
  4. チェックボックスの上のプルダウンを「ブログ」に設定
  5. 横にプルダウンが表示されるので「お知らせ」を選択
  6. 変更ボタンをクリック


以上でエントリーの移行は完了です。「お知らせ」の子ブログに移動すると、エントリーの情報が表示されているのが確認できます。

トップページに子ブログの情報を表示させる

この段階でトップページにアクセスすると、お知らせのカテゴリーを表示させる設定になっていたモジュールID の設定では表示ができなくなります。



管理ページ / モジュールID を開き、モジュールID top_headline の条件設定を開きます。



引数のカテゴリーIDの「お知らせ」を削除し、ブログの「お知らせ」を選択します。これで再度、トップページを開くと「お知らせ」の一覧が表示されるようになります。

親ブログのモジュールIDを子ブログでも利用する

ナビゲーション

お知らせの一覧や詳細ページにアクセスすると、ヘッダーやナビゲーション、フッターの情報が消えていることが確認できます。a-blog cms の情報は、上層のブログは下層のブログのデータを利用することはできますが、下層のブログ(子ブログ)は親のモジュールIDが見えません。



お知らせ」の子ブログのモジュールIDの一覧にアクセスしてみると、何もないことが確認できます。



次に、親ブログのモジュールIDの一覧にアクセス、グローバルナビゲーション id="nav_global" の条件設定を開いて、グローバル「下の階層のブログが利用することを許可する」にチェックをつけ保存します。



こうすることで、親のモジュールID は子での利用が許可され、表示されるようになります。



トピックパス

トピックパスには「お知らせ」しか表示されておらず、本来は HOME > お知らせ という表示でいて欲しいところです。グローバルナビゲーション id="nav_global と同様にグローバルのチェックだけつけても、今回は思ったように表示してくれません。

条件設定

カテゴリーの階層設定について「下層のカテゴリーも含める」という設定を以前行なっていますが、ブログも階層構造になっていますので、同様に「下層のブログも含める」設定に変更してください。



表示設定

階層設定に 1 が設定されていることから、親ブログしか表示できていません。表示できる階層数を増やすか、空にして全階層を表示させる設定にします。



これで、 ブログ名 > 子ブログ名 > エントリー名と表示できるようになりました。



試しに、子ブログ内に、カテゴリーと子カテゴリーを作成し、エントリーを用意して階層が表示されるかもテストしておいた方がいいかもしれません。



このようにブログの階層構造と、カテゴリーの階層構造を自動的にリンクを生成します。

ブログフィールドをモジュールIDを設定する

親ブログのページと比べて、残り表示ができていないのは、ヘッダーとフッターのカスタムフィールドが表示できていません。



カスタムフィールドの表示は、ブログフィールドで表示させていますが、これにモジュールIDを設定し、グローバルの設定を行います。 ここで大事なのは、ブログID に親ブログを設定しておくことです。



<!-- BEGIN_MODULE Blog_Field id="global" -->
<div class="header-logo">
  <div>
    <h1 class="site-name"><a href="index.html">
        <img src="%{MEDIA_ARCHIVES_DIR}{site-icon@path}" alt="{site-name}" class="site-logo"><span
          class="siteNameText">{site-name}</span></a>
    </h1>
  </div>
</div>
<!-- END_MODULE Blog_Field -->

フッターにあるブログフィールドモジュールにも同様に id="global" を設定します。

シークレットブログについて

ブログのステータスとして、公開(利用する)・非公開(利用を停止する)以外に、シークレットという設定が存在します。この設定にすることでログインしていないと閲覧できない会員制コンテンツを作ることができます。



会員は、シークレットブログ上に作成し、権限を読者に設定することでエントリーを作ることはできない閲覧専用のユーザーとして運用が可能です。また、読者ユーザーはライセンスのユーザー数に含まれず、読者登録の機能も標準で用意されています。設定は、コンフィグのログイン設定をご覧ください。



グローバルカテゴリーについて

今回は「お知らせ」の子ブログということで、設定しませんでしたが、例えば多店舗展開のウェブサイトを作る際には、店舗ブログ毎にカテゴリーを作るのではなく、親ブログ側のカテゴリーをモジュールIDのようにグローバル化することが可能です。



これで、親ブログ側で各店舗の特定のカテゴリーの新着を簡単に表示するモジュールIDを作ることができるようになります。

コンフィグセットについて

コンフィグの管理画面にアクセスすると、毎回「このブログの初期コンフィグ」を選択していましたが、このコンフィグは増やしたり、再利用が可能になっています。



(コンフィグセットの作成)で、名前をつけたコンフィグセットを作ることができ、これもグローバル化することで、子ブログでコンフィグを共有できるようになります。



子ブログ「お知らせ」のブログ管理の画面で選択できるようになりました。あまり「お知らせ」では使うことはないかもしれませんが、多店舗ブログのような店舗ブログを作るたびに各設定を細かくすることなく、このコンフィグセットを選択するだけで他の店舗と同じ設定にすることができます。



さらに、カテゴリーにもコンフィグセットの設定は存在しています。 こちらも、うまく活用すると便利なこともあります。



最後に

今回は、ブログの階層化をメインに、他のブログで設定を再利用するグローバル化について紹介しました。これで、カテゴリーであった「お知らせ」を、子ブログで管理できるようにし、子ブログ用の子テーマ news@sample の実装が完了したことになります。

Twitterで「子ブログ編」完了をシェアする


静的HTMLサイトからCMSのテーマを作ってみよう 3「モジュール編」


はじめに

「静的HTMLサイトからCMSのテーマを作ってみよう」では、静的HTMLファイルをa-blog cmsで利用できるようなテンプレートファイルに編集し、最終的には1つのオリジナルテーマを作成していきます。

このページは 静的HTMLサイトからCMSのテーマを作ってみよう 2「カスタムフィールド編」 の続きになります。

またチュートリアルの実践環境として、本編ではローカルサーバー http://localhost を使用して説明しておりますが、以下のフォームから実際に作業をするサーバーのURLを入れていただく事で、文中のテキストを希望のURLに書き換えることができます。ぜひご活用ください。

タイトルタグを動的に変更する

現在、<head> 内の <title> 〜 </title> について初期状態のままですので、この部分も自動で編集されるように実装を進めます。

> エントリータイトル | カテゴリー名 | ブログ名

タイトルタグについては、OGPモジュールというモジュールが用意されておりますので、タイトルタグに加え、<meta>部分もこれで対応が可能です。

<!-- BEGIN_MODULE Ogp -->
<title>{title}</title>
<meta property="og:url" content="%{PERMALINK}">
<meta property="og:site_name" content="%{ROOT_BLOG_NAME}">
<meta property="og:title" content="{title}">
<meta property="og:type" content="{type}">
<!-- BEGIN_IF [{description}[delnl]/nem/] -->
<meta property="og:description" content="{description}[mb_trim(350, '...')|delnl|escape]"><!-- END_IF --><!-- BEGIN_IF [{image}/nem/] -->
<!-- BEGIN_IF [{image@type}/eq/media] -->
<meta property="og:image" content="http://localhost/media/{image}">
<meta property="og:image:secure_url" content="http://localhost/media/{image}" />
<!-- ELSE -->
<meta property="og:image" content="http://localhost/archives/{image}">
<meta property="og:image:secure_url" content="http://localhost/archives/{image}" />
<!-- END_IF -->
<meta property="og:image:width" content="{image@x}" />
<meta property="og:image:height" content="{image@y}" /><!-- END_IF --><!-- BEGIN_IF [{description}[delnl]/nem/] -->
<meta name="description" content="{description}[mb_trim(350, '...')|delnl|escape]"><!-- END_IF --><!-- BEGIN_IF [{keywords}/nem/] -->
<meta name="keywords" content="{keywords}"><!-- END_IF -->
<!-- END_MODULE Ogp -->

このスニペットでもいいのですが、beginnerテーマの中に用意されている /themes/beginner/include/head/meta.html を利用した方が Twitterカードについても対応されているのでオススメかもしれません。

sampleフォルダーに includeフォルダーを作成し、その中に headフォルダーを作り、meta.html ファイルをコピーしてきます。

index.html , list.html , entry.html の <title> <meta> を削除して

@include("/include/head/meta.html")

に置き換えます。このインクルード機能について説明ができていませんので、次でしっかり説明をします。

インクルード機能でファイルをまとめる

テンプレートの HTML の中で、別の HTML を読み込む機能をインクルード機能と呼びます。

一般的に、ヘッダー部分やフッター部分については、どのページでも同様なことが多いので、 header.htmlfooter.html のようなファイルを用意し各ファイルからインクルードします。 フォルダー名の決まりはありませんが、include にまとめるのが a-blog cms の一般的なルールになっています。

@include("/include/header.html")
	
@include("/include/footer.html")

さらに、インストール時に最初から用意されている beginnerテーマを参考に紹介しておきますが、基本はモジュール単位でファイル分けインクルードするようにしています。

<!DOCTYPE html>
<html class="no-js" lang="ja">
<head>
  @include("/include/head/meta.html")
  @include("/include/head/link.html")
  @include("/include/head/js.html")
</head>
<body>
<!-- ヘッダー -->
@include("/include/header.html")
<div class="acms-container js-pretty-scroll-container">
  <!-- ※管理用パーツ -->
  @include("/admin/action.html")
  @include("/include/header/top-image.html")
  <div class="acms-grid">
    <main class="acms-col-lg-9 main">
      <div class="main-inner is-space-right">
        <!-- エントリーヘッドライン(トップ用) -->
        @include("/include/entry/headline-top.html")
        <!-- エントリーサマリー -->
        @include("/include/entry/summary-top.html")
        <!-- 確認用テンプレート --> 
        @include("/include/check-seo.html")
      </div>
    </main>
    <div class="acms-col-lg-3 side">
      <div class="js-pretty-scroll">
        <!-- 検索フォーム -->
        @include("/include/parts/search.html")
        <!-- ピックアップリスト -->
        @include("/include/entry/summary-pickup.html")
        <!-- バナー -->
        @include("/include/siteparts/banner.html")
        <!-- リンクリスト -->
        @include("/include/siteparts/link-list.html")
        <!-- モバイル:ナビゲーションメニュー -->
        @include("/include/parts/mobile-nav.html")
        <!-- ログインボタン -->
        @include("/include/parts/login-button.html")
      </div>
    </div>
  </div>
</div>
<!-- お問い合わせ -->
@include("/include/footer/suggest.html")
<!-- フッター -->
@include("/include/footer.html")
</body>
</html>

グローバルナビゲーションの実装

ナビゲーションは index.html , list.html , entry.html どのページにもあります。この段階では、インクルード機能でしっかりファイル分けができているようであれば、1つのファイルのみ修正すればいい事になっています。

<div class="header-nav">
  <div class="acms-grid">
    <nav class="navbar">
      <ul>
        <li><a href="index.html">ホーム</a></li>
        <li class="stay"><a href="list.html">一覧</a></li>
        <li><a href="entry.html">詳細</a></li>
      </ul>
    </nav>
  </div>
</div>

<div class="header-nav"> の辺りを Navigation に置き換えていきます。 Navigation モジュールは、<ul><li> で書かれていますが、入れ子構造にできる仕様になっており、それを1つの <!-- BEGIN navigation:loop --> 〜 <!-- END navigation:loop --> で作られているので制御用のブロックが多く分かりにくいです。

<!-- BEGIN_MODULE Navigation -->
<div>
  @include("/admin/module/setting.html")
  <div class="acms-navbar acms-margin-bottom-medium clearfix">
  <!-- BEGIN navigation:loop -->
    <!-- BEGIN ul#front --><ul><!-- END ul#front -->
      <!-- BEGIN li#front --><li {attr} class="c_{level}" ><!-- END li#front -->
        <!-- BEGIN link#front --><a href="{url}" {attr} target="{target}"><!-- END link#front -->
        <!-- BEGIN label:veil -->{label}[raw]<!-- END label:veil -->
        <!-- BEGIN link#rear --></a><!-- END link#rear -->
      <!-- BEGIN li#rear --></li><!-- END li#rear -->
    <!-- BEGIN ul#rear --></ul><!-- END ul#rear -->
  <!-- END navigation:loop -->
  </div>
</div>
<!-- END_MODULE Navigation -->

<nav class="navbar"> の中にある <ul> 〜 </ul> を <!-- BEGIN navigation:loop --> 〜 <!-- END navigation:loop --> に置き換えるような感じで実装を進めてください。

最終的には、以下のようになります。もちろんモジュールIDの設定 id="nav_global" も忘れずに行ってください。

<!-- BEGIN_MODULE Navigation id="nav_global" -->
<div class="header-nav">
  <div class="acms-grid">
    <nav class="navbar">
  <!-- BEGIN navigation:loop -->
    <!-- BEGIN ul#front --><ul><!-- END ul#front -->
    <!-- BEGIN li#front --><li {attr} class="c_{level}" ><!-- END li#front -->
      <!-- BEGIN link#front --><a href="{url}" {attr} target="{target}"><!-- END link#front -->
      <!-- BEGIN label:veil -->{label}[raw]<!-- END label:veil -->
      <!-- BEGIN link#rear --></a><!-- END link#rear -->
    <!-- BEGIN li#rear --></li><!-- END li#rear -->
    <!-- BEGIN ul#rear --></ul><!-- END ul#rear -->
  <!-- END navigation:loop -->
    </nav>
  </div>
</div>
<!-- END_MODULE Navigation -->

モジュールIDの条件設定しか行っていない人は、何も表示されずに焦った人もいることでしょう。表示設定側を以下のように行ってください。



画像だとコピぺできないので、表にも書いておきます。

ラベルURL属性
HOME%{HOME_URL}class="js-link_match_location-full"
会社概要%{HOME_URL}company/class="js-link_match_location"
物件情報%{HOME_URL}realestate/class="js-link_match_location"
お知らせ%{HOME_URL}news/class="js-link_match_location"
採用情報%{HOME_URL}recruit/class="js-link_match_location"
お問い合せ%{HOME_URL}contact/class="js-link_match_location"

class="js-link_match_location" について解説しておきます。

この class をつけておくと、そのディレクトリーを表示している時に class="stay" を JavaScript でつけてくれます。例えば、/news/ の時と /news/entry-11.html どちらでも今は「お知らせ」にいますを伝えるためです。

HOME だけは、少し違って class="js-link_match_location-full" と設定されているので完全一致している時という指定になります。

属性は <li> に設定したい class などを、子要素属性には <a> に追記したい class などを設定できるようになっています。



トップページのスライダーの画像を変更できるように実装

top.html のスライダー部分を探してみます。

<div class="module-section">
  <div class="js-slider">
    <div>
      <a href="list.html" target="_self" class="slider-item"><img src="/images/slider_zoo1.jpg" width="1150" height="400" alt="" class="acms-img-responsive slider-image" /></a>
    </div>
    <div>
      <a href="list.html" target="_self" class="slider-item"><img src="/images/slider_zoo2.jpg" width="1150" height="400" alt="" class="acms-img-responsive slider-image" /></a>
    </div>
    <div>
      <a href="list.html" target="_self" class="slider-item"><img src="/images/slider_zoo3.jpg" width="1150" height="400" alt="" class="acms-img-responsive slider-image" /></a>
    </div>
  </div>
</div>

スライダーは JavaScript で実装されており、上記のような HTML になっています。 class のついていない <div> 部分が3つ同じ構造になっているのが確認できます。

メディアバナーモジュールを利用して実装していきます。バナーというとサブカラムにある a-blog cms のロゴみたいなものを想像しますが、複数件の画像とリンクを管理できればどのようなモジュールでも大丈夫ではありますが、Media_Banner モジュールを利用するとバナーの表示期間の設定も活用できるので便利に使えるのではないでしょうか。

<!-- BEGIN_MODULE Media_Banner -->
<div>
@include("/admin/module/setting.html")
<ul class="acms-list-nostyle acms-grid">
  <!-- BEGIN banner:loop -->
  <li class="acms-col-md-4">
    <!-- BEGIN banner#src -->
    {src}[raw]
    <!-- END banner#src -->
    <!-- BEGIN banner#img -->
    <a href="{url}" target="{target}"><img src="%{MEDIA_ARCHIVES_DIR}{img}" width="{x}" height="{y}" class="acms-img-responsive" alt="{alt}" /></a>
    <!-- END banner#img -->
  </li>
  <!-- END banner:loop -->
</ul>
</div>
<!-- END_MODULE Media_Banner -->

元の HTML を挟むように <!-- BEGIN_MODULE Media_Banner --> 〜 <!-- END_MODULE Media_Banner --> を追記し、モジュールID id="top_image" を設定します。

<!-- BEGIN_MODULE Media_Banner id="top_image" -->
<div class="module-section">
  <div class="js-slider">
    <!-- <div>
      <a href="list.html" target="_self" class="slider-item"><img src="/images/slider_zoo1.jpg" width="1150" height="400" alt="" class="acms-img-responsive slider-image" /></a>
    </div> -->
    <!-- BEGIN banner:loop -->
    <!-- BEGIN banner#img -->
    <div>
      <a href="{url}" target="_self" class="slider-item"><img src="%{MEDIA_ARCHIVES_DIR}{img}" width="{x}" height="{y}" alt="{alt}" class="acms-img-responsive slider-image" /></a>
    </div>
    <!-- END banner#img -->
    <!-- END banner:loop -->
  </div>
</div>
<!-- END_MODULE Media_Banner -->

3つのループのうちの1つをコメントタグで囲み残しておき、2つ目の<div>をスニペットを参考に{変数}に置き換えていきます。3つ目の<div>は削除しました。

トピックパスを実装

トピックパス(パンくずリスト) は index.html には用意していませんが list.html , entry.html に用意されています。

<nav class="topicpath">
 <ol class="topicpath-list acms-container sp-container clearfix">
  <li class="topicpath-item"><a href="index.html" class="topicpath-link">HOME</a></li>
  <li class="topicpath-item"><a href="list.html" class="topicpath-link">カテゴリー名</a></li>
 </ol>
</nav>
<nav class="topicpath">
 <ol class="topicpath-list acms-container sp-container clearfix">
  <li class="topicpath-item"><a href="index.html" class="topicpath-link">HOME</a></li>
  <li class="topicpath-item"><a href="list.html" class="topicpath-link">カテゴリー名</a></li>
  <li class="topicpath-item"><a href="entry.html" class="topicpath-link">エントリー名</a></li>
 </ol>
</nav>

この部分を、どちらも @include("/include/topicpath.html") として、topicpath.html を用意します。

<!-- BEGIN_MODULE Topicpath -->
<ol class="acms-topicpath acms-margin-bottom-mini clearfix">
 <!-- BEGIN blog:loop -->
 <li><a href="{url}">{name}</a></li><!-- END blog:loop --><!-- BEGIN category:loop -->
 <li><a href="{url}">{name}</a></li><!-- END category:loop --><!-- BEGIN entry -->
 <li><a href="{url}">{title}</a></li><!-- END entry -->
</ol>
<!-- END_MODULE Topicpath -->

Topicpathスニペットtopicpath.html にコピペして <nav>とモジュールID を追加し、class を移植していきます。 完成形は以下のようになります。

<!-- BEGIN_MODULE Topicpath id="topicpath" -->
<nav class="topicpath">
<ol class="topicpath-list acms-container sp-container clearfix">
 <!-- BEGIN blog:loop -->
 <li class="topicpath-item"><a href="{url}" class="topicpath-link">{name}</a></li><!-- END blog:loop --><!-- BEGIN category:loop -->
 <li class="topicpath-item"><a href="{url}" class="topicpath-link">{name}</a></li><!-- END category:loop --><!-- BEGIN entry -->
 <li class="topicpath-item"><a href="{url}" class="topicpath-link">{title}</a></li><!-- END entry -->
</ol>
</nav>
<!-- END_MODULE Topicpath -->

Topicpathモジュールの条件設定

トピックパスモジュールでは、条件設定タブの引数についてカテゴリーとエントリーにチェックをつけるのを忘れないようにしてください。



また、モジュールID を設定すると階層の指定が可能になります。 例えば「お知らせ」カテゴリーの子カテゴリーに「テスト」というカテゴリーを作った時に「下階層のカテゴリーも含める」を選択するようにしてください。

階層設定では

  • 下階層を含めない
  • 下階層も含める
  • 下階層のみを対象とする

の3種類でデータの絞り込み範囲を設定ができます。

Topicpathモジュールのみ、階層の範囲が下階層ではなく上階層になっています。

Topicpathモジュールの表示設定

表示設定タブでは、何も指定しないとトピックパスにブログ名が最初に表示されますので、HOME や TOP などの表記にしておきます。



トピックパスモジュールを利用すると、ブログ > 子ブログ > カテゴリー > 子カテゴリー > エントリー のように階層が自動的に作られ、リンクの設定もされます。



サイト内検索機能を実装する

各ページのサブカラムに用意されている検索フォームが機能するように実装していきます。

<div class="module-section">
  <section class="search">
    <div class="module-header clearfix">
      <h2 class="module-heading">検索</h2>
    </div>
    <form action="" method="post" name="searchForm" class="acms-form search-form" role="search">
      <div class="acms-form-action">
        <input type="search" id="searchForm" name="keyword" value="" size="15" class="search-form-input">
        <span class="acms-form-side-btn"><button type="submit" name="submit" class="acms-btn btn-search"><span class="acms-icon-search"></span><span class="acms-hide-visually">検索</span></button></span>
      </div>
    </form>
  </section>
</div>

この部分を少し書き換えます。

<div class="module-section">
  <section class="search">
    <div class="module-header clearfix">
      <h2 class="module-heading">検索</h2>
    </div>
    <form action="" method="post" name="searchForm" class="acms-form search-form" role="search">
      <div class="acms-form-action">
        <input type="search" id="searchForm" name="keyword" value="%{KEYWORD}" size="15" class="search-form-input">
        <input type="hidden" name="query" value="keyword">
        <span class="acms-form-side-btn"><button type="submit" name="ACMS_POST_2GET" class="acms-btn btn-search"><span class="acms-icon-search"></span><span class="acms-hide-visually">検索</span></button></span>
        <input type="hidden" name="tpl" value="/entry.html">
        <input type="hidden" name="bid" value="1">
      </div>
    </form>
  </section>
</div>

ポイントは以下の4点です。

  1. 既存のコードの input タグ内 value の空欄にvalue="%{KEYWORD}"を追加
  2. 既存のコードの button タグ内name="submit" をname="ACMS_POST_2GET"に書き換え
  3. input type="hidden" name="tpl" でPOST後のテンプレートファイルを指定
  4. type="hidden" name="bid" value="1" で検索範囲を指定(1:全部)

グローバル変数の %{KEYWORD} は、検索ワードを表示させる変数になります。

テンプレートのファイル名を変更し、テーマ設定ファイルを作る

静的なHTMLファイルだけで構成されていたウェブサイトが、a-blog cms を利用してブラウザからコンテンツの追加や更新が可能なサイトに生まれ変わりました。今回作ったテーマ sample をテーマ設定でテーマ名を選択するだけで動作するように設定ファイルを作ることと、ファイル名を標準的なものに変更します。

種類旧ファイル名新ファイル名
トップindex.html_top.html
一覧list.htmlindex.html
詳細entry.html_entry.html

ファイル名の先頭にあるアンダーバーについて少し説明しておくと、アンダーバー付きのファイルはブラウザから見えなくなります。

http://localhost/http://localhost/top.html どちらでもページが出てしまわないように http://localhost/_top.html とすることで _top.html のリンク先は 404 not found になることが確認できます。

/themes/sample/template.yaml を最後に用意します。 上記のファイル名の変更で /themes/beginner/template.yaml からコピーしても同様ですが、以下をコピペしても大丈夫です。

tpl_top         : _top.html
tpl_index       : index.html
tpl_detail      : _entry.html
tpl_404         : 404.html
tpl_admin       : admin.html
tpl_entry_edit  : _entry.html
tpl_entry_add   : _entry.html
tpl_login       : login.html

最後に

今回は、いろいろなモジュールを中心に紹介しました。

  • OGPモジュール
  • インクルード処理
  • Navigationモジュール
  • Media_Bannerモジュール
  • Topicpathモジュール
  • サイト内検索機能
  • テーマファイルを作る

について紹介しました。

これで小規模なサイトのテーマ作成における大まかな一連の作業が終了しました。 どこにも PHP や JavaScript の実装はなく、 HTML と管理画面の設定で CMS 化の作業が完了します。

ぜひ、次はご自身で用意したオリジナルの静的HTMLファイルをベースとしたテーマ作成にチャレンジしてみてください。

Twitterで「モジュール編」完了をシェアする



これまでに1−3で作ったテーマを、階層化された複数のブログで利用する構成にする「子ブログ編」についてもお時間があれば、あわせて学習ください。

これまで で作ったテーマを利用し、階層化された複数のブログで利用する構成にする「子ブログ編」もしくは「フォーム編」どちらからでも大丈夫です。お時間があれば、合わせて学習ください。

静的HTMLサイトからCMSのテーマを作ってみよう2「カスタムフィールド編」


はじめに

「静的HTMLサイトからCMSのテーマを作ってみよう」では、静的HTMLファイルをa-blog cmsで利用できるようなテンプレートファイルに編集し、最終的には1つのオリジナルテーマを作成していきます。

このページは 静的HTMLサイトからCMSのテーマを作ってみよう 1「エントリー編」 の続きになります。

またチュートリアルの実践環境として、本編ではローカルサーバー http://localhost を使用して説明しておりますが、以下のフォームから実際に作業をするサーバーのURLを入れていただく事で、文中のテキストを希望のURLに書き換えることができます。ぜひご活用ください。

カスタムフィールドとは

管理画面上に標準で用意されている入力欄ではなく、カスタマイズする人が欲しい追加された入力欄のことです。一般的にテーマ作成では、サイトの閲覧者がアクセスする表側のテンプレートを作ることになりますが、カスタムフィールドについては管理画面のテンプレートを作ることで希望の管理画面の UI を構築していきます。



カスタムフィールドの種類と、そのテンプレートのファイルの置き場は以下のようになります。

カスタムフィールドの種類テンプレートファイル
エントリー カスタムフィールド/themes/sample/admin/entry/field.html
カテゴリー カスタムフィールド/themes/sample/admin/category/field.html
ブログ カスタムフィールド/themes/sample/admin/blog/field.html
ユーザー カスタムフィールド/themes/sample/admin/user/field.html
モジュール カスタムフィールド/themes/sample/admin/module/field.html

カスタムフィールドの作り方

a-blog cms のカスタムフィールドは、フォームの HTML を用意するのですが、入力ミスで動作しなくなることから「カスタムフィールドメーカー」というツールが管理ページやデベロッパーサイト上で提供されています。管理ページのカスタムフィールドメーカーには、クイックサーチ(どこでも検索) でアクセスしてみましょう。

  • Windows: Ctrl + k
  • MacOS: ⌘K

の検索窓に「カスタムフィールドメーカー」と入れればサジェストされます。

カスタムフィールドメーカー



ヘッダー・フッターの編集用の管理画面の作成

カスタムフィールドの基礎の紹介が終わったので、ここからテンプーレートを実装を進めます。このヘッダー・フッター部分は、サイト全体どこでも利用するデータということになりますので、ブログのカスタムフィールドを利用します。



ヘッダー部分は、アイコンとタイトルを編集可能にします。



フッター部分は、左側の会社名・郵便番号・住所・電話番号と、右側にある SNSアイコンのリンク先を設定したり、使わないものは消したりできるようにしてみます。

ブログのカスタムフィールドの記述については、 /themes/sample/admin/blog/field.html に記述しますが、 /admin/blog/field.html は、存在していないため admin ディレクトリを作成し、blog ディレクトリを作成し、その中に空の field.html ファイルを作成する必要があります。

その後、カスタムフィールドメーカーを利用して以下の情報から管理画面のフォームのHTMLを作成します。

ヘッダー情報

入力欄の種類タイトルフィールド
メディアアイコンsite-icon
テキストサイト名site-name
<table class="acms-admin-table-admin-edit">
  <tr>
    <th>アイコン</th>
    <td class="js-media-field">
      <div class="js-droparea" data-thumbnail="{site-icon@thumbnail}" data-type="image" data-thumbnail-type="{site-icon@type}" data-width="200px" data-height="200px"></div>
      <p class="js-text acms-admin-text-danger" style="display:none">許可されていないファイルのため挿入できません。</p>
      <div class="acms-admin-margin-top-mini">
        <button type="button" class="js-insert acms-admin-btn" data-type="image">メディアを選択</button>
      </div>
      <input type="hidden" name="site-icon" value="{site-icon}" class="js-value" />
      <input type="hidden" name="field[]" value="site-icon" />
      <input type="hidden" name="site-icon:extension" value="media" />
    </td>
  </tr>
  <tr>
    <th>サイト名 </th>
    <td>
      <input type="text" name="site-name" value="{site-name}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="site-name" />
    </td>
  </tr>
</table>

会社情報

入力欄の種類タイトルフィールド
テキスト会社名company-name
テキスト郵便番号zip
テキスト住所address
テキスト電話番号tel
<table class="acms-admin-table-admin-edit">
  <tr>
    <th>会社名</th>
    <td>
      <input type="text" name="company-name" value="{company-name}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="company-name" />
    </td>
  </tr>
  <tr>
    <th>郵便番号</th>
    <td>
      <input type="text" name="zip" value="{zip}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="zip" />
    </td>
  </tr>
  <tr>
    <th>住所</th>
    <td>
      <input type="text" name="address" value="{address}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="address" />
    </td>
  </tr>
  <tr>
    <th>電話番号</th>
    <td>
      <input type="text" name="tel" value="{tel}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="tel" />
    </td>
  </tr>
</table>

SNS情報    

入力欄の種類タイトルフィールド
テキストFacebookfacebook
テキストTwittertwitter
テキストYouTubeyoutube
<table class="acms-admin-table-admin-edit">
  <tr>
    <th>Facebook</th>
    <td>
      <input type="text" name="facebook" value="{facebook}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="facebook" />
    </td>
  </tr>
  <tr>
    <th>Twitter</th>
    <td>
      <input type="text" name="twitter" value="{twitter}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="twitter" />
    </td>
  </tr>
  <tr>
    <th>YouTube</th>
    <td>
      <input type="text" name="youtube" value="{youtube}" class="acms-admin-form-width-full" />
      <input type="hidden" name="field[]" value="youtube" />
    </td>
  </tr>
</table>

これらをテンプレート上に設定すると ブログ管理のカスタム設定 に入力欄が表示されます。

またタグの上にh2などの見出しを設置しておくことでた各項目の区切り分かりやすくなります。

<h2>ヘッダー情報</2>


ここまで作ると、次は表示側のテンプレートの実装になります。

ヘッダーの表示側の実装

管理画面が出来上がると、次はそのデータを表示できるようにします。

今回はブログのカスタムフィールドを表示させます。表示にはブログフィールドを利用します。カスタムフィールドモジュールの中で利用する {変数} は、制作者側で用意していますので、中身は空っぽになっています。

<!-- BEGIN_MODULE Blog_Field -->

<!-- END_MODULE Blog_Field -->

修正する場所は <div class="header-logo"> になります。

<div class="header-logo">
  <div>
    <h1 class="site-name"><a href="index.html">
      <img src="/images/ablogcms_mark.png" alt="ablogcms" class="site-logo"><span class="siteNameText">sample static site</span></a>
    </h1>
  </div>
</div>

表示用のコードについても、カスタムフィールドメーカーの表示用ソースを参考に、以下のように書き換えます。

<!-- BEGIN_MODULE Blog_Field -->
<div class="header-logo">
  <div>
    <h1 class="site-name"><a href="index.html">
      <img src="%{MEDIA_ARCHIVES_DIR}{site-icon@path}" alt="{site-name}" class="site-logo"><span class="siteNameText">{site-name}</span></a>
    </h1>
  </div>
</div>
<!-- END_MODULE Blog_Field -->

IFブロックを利用して条件分岐の設定をする

先ほど最低限の実装を済ませましたが、もう少ししっかり作り込みを行います。 CMS ではデータがある時に出すのは当たり前ではありますが、無い時にどうするのかも大事です。例えばアイコンが無い時に何もしてないと、画像のパスが無いままだけ残ってしまうことになります。

IFブロックを利用するとテンプレートに条件分岐を設定できます。


<div class="header-logo">
  <div>
    <h1 class="site-name"><a href="index.html">
      <!-- BEGIN_IF [{site-icon@path}/nem] -->
      <img src="%{MEDIA_ARCHIVES_DIR}{site-icon@path}" alt="{site-name}" class="site-logo">
      <!-- END_IF -->
      <span class="siteNameText">
      <!-- BEGIN_IF [{site-name}/nem] -->
        {site-name}
      <!-- ELSE -->
        %{BLOG_NAME}
      <!-- END_IF -->
    </span>
    </a>
    </h1>
  </div>
</div>

フッターの表示側の実装

ヘッダーと同じようにフッター部分も実装をしていきます。こちらもデータが無い時にタグが残らないような実装をする必要がありますが、IFブロックより手軽な :veilブロック <!-- BEGIN xxx:veil --> 〜 <!-- END xxx:veil --> を使ってみます。

:veilブロックは、 BEGIN 〜 END の中に {変数} が複数あったとして、何も編集されなかったら、囲まれているエリアは無かったことにできるというブロックです。


編集前

<address class="acms-col-md-4">
  <dl class="company-about">
    <dt class="company-name">有限会社アップルップル</dt>
    <dd class="company-detail">〒450-0002</dd>
    <dd class="company-detail">名古屋市中村区名駅3-18-5 モンマートビル5F</dd>
    <dd class="company-detail">TEL : <a href="tel:052-485-8577">052-485-8577</a></dd>
  </dl>
</address>
<div class="acms-col-md-8">
  <div class="acms-hide acms-block-lg acms-block-xl">
    <ul class="sns-list">
      <li class="sns-list-item"><a href="https://www.facebook.com/ablogcms" class="sns-list-facebook"><span class="acms-icon-facebook"></span></a></li>
      <li class="sns-list-item"><a href="https://twitter.com/ablogcms" class="sns-list-twitter"><span class="acms-icon-twitter"></span></a></li>
      <li class="sns-list-item"><a href="https://www.youtube.com/user/ablogcmsTube" class="sns-list-youtube"><span class="acms-icon-youtube"></span></a></li>
    </ul>
  </div>
</div>

以下のような実装になりました。{変数}毎に :veil で囲み、データが無い時には、<dd> が無くなるように設定しています。全部書いてない時には <dl> や <ul> も消えるように company:veil というものも用意しました。その外の <address class="acms-col-md-4"> や <div class="acms-col-md-8"> を囲むとレイアウトがズレる可能性があるので残すようにしています。

<!-- BEGIN_MODULE Blog_Field -->
<address class="acms-col-md-4">
  <!-- BEGIN company:veil -->
  <dl class="company-about">
    <!-- BEGIN company-name:veil --><dt class="company-name">{company-name}</dt><!-- END company-name:veil -->
    <!-- BEGIN zip:veil --><dd class="company-detail">〒{zip}</dd><!-- END zip:veil -->
    <!-- BEGIN address:veil --><dd class="company-detail">{address}</dd><!-- END address:veil -->
    <!-- BEGIN tel:veil --><dd class="company-detail">TEL : <a href="tel:{tel}">{tel}</a></dd><!-- END tel:veil -->
  </dl>
  <!-- END company:veil -->
</address>
<div class="acms-col-md-8">
  <!-- BEGIN sns:veil -->
  <div class="acms-hide acms-block-lg acms-block-xl">
    <ul class="sns-list">
      <!-- BEGIN facebook:veil --><li class="sns-list-item"><a href="{facebook}" class="sns-list-facebook"><span class="acms-icon-facebook"></span></a></li><!-- END facebook:veil -->
      <!-- BEGIN twitter:veil --><li class="sns-list-item"><a href="{twitter}" class="sns-list-twitter"><span class="acms-icon-twitter"></span></a></li><!-- END twitter:veil -->
      <!-- BEGIN youtube:veil --><li class="sns-list-item"><a href="{youtube}" class="sns-list-youtube"><span class="acms-icon-youtube"></span></a></li><!-- END youtube:veil -->
    </ul>
  </div>
  <!-- END sns:veil -->
</div>
<!-- END_MODULE Blog_Field -->

カテゴリー毎のヘッダーの実装

次は list.htmlentry.html のヘッダー部分の仕上げを行います。現状は、カテゴリー名と書かれていますが、それぞれのカテゴリー名が編集されるようにします。また、黒い部分には背景画像を設定し、「カテゴリーの説明文が書かれます。」の部分も編集可能にします。



まずは修正する場所は <div class="page-title-wrapper"> になります。

<div class="page-title-wrapper" style="background-image: url(/images/header.jpg);">
  <div class="page-title-filter"></div>
  <div class="page-title-inner">
  	<div class="acms-container">
    <p class="page-title">カテゴリー名</p>
    <p class="page-description">カテゴリーの説明文が書かれます。</p>
  	</div>
  </div>
</div>

グローバル変数を利用

a-blog cms のグローバル変数を利用すると、簡単にカテゴリー名が設定できます。通常の変数は中括弧(波括弧)を利用して {変数} を設定しますが、グローバル変数は %{変数} のように中括弧の前にパーセントがついています。どのようなグローバル変数があるのかは、デベロッパーサイトのドキュメントのグローバル変数をご覧ください。


ヘッダー部分でも実は %{BLOG_NAME} と実装結果の HTML には書いてありましたが、カテゴリー毎に変わっているところで確認してもらった方が分かりやすいかと説明しないでいました。

カテゴリー名のグローバル変数は %{CATOGORY_NAME} と書きます。

<div class="page-title-wrapper" style="background-image: url(/images/header.jpg);">
  <div class="page-title-filter"></div>
  <div class="page-title-inner">
  	<div class="acms-container">
    <p class="page-title">%{CATEGORY_NAME}</p>
    <p class="page-description">カテゴリーの説明文が書かれます。</p>
  	</div>
  </div>
</div>

これで http://localhost/news/http://localhost/recruit/ を表示させると「お知らせ」や「採用情報」という表示が出るようになります。

カテゴリーカスタムフィールド管理画面の作成

次に、背景画像と説明文はカテゴリーのカスタムフィールドを利用します。項目としては以下のような項目になりますので、カスタムフィールドメーカーを利用し管理画面のフォームのHTMLを作成します。入力用ソース のエリアに書かれたフォームのHTMLを単体のファイルとして、 /themes/sample/admin/category/field.html に保存します。

入力欄の種類タイトルフィールド
メディア背景画像category-image
テキストエリア説明文category-description
<table class="acms-admin-table-admin-edit">
  <tr>
    <th>背景画像</th>
    <td class="js-media-field">
    <div class="js-droparea" data-thumbnail="{category-image@thumbnail}" data-type="image" data-thumbnail-type="{category-image@type}" data-width="200px" data-height="200px"></div>
    <p class="js-text acms-admin-text-danger" style="display:none">許可されていないファイルのため挿入できません。</p>
    <div class="acms-admin-margin-top-mini">
      <button type="button" class="js-insert acms-admin-btn" data-type="image">メディアを選択</button>
    </div>
    <input type="hidden" name="category-image" value="{category-image}" class="js-value" />
    <input type="hidden" name="field[]" value="category-image" />
    <input type="hidden" name="category-image:extension" value="media" />
    </td>
  </tr>
  <tr>
    <th>説明文</th>
    <td>
    <textarea name="category-description" class="acms-admin-form-width-full">{category-description}</textarea>
    <input type="hidden" name="field[]" value="category-description" />
    </td>
  </tr>
</table>

これらをテンプレート上に設定すると カテゴリー管理 の管理画面の 例えばお知らせ」のカスタム設定 を確認してみると、入力欄が表示されます。



カテゴリーカスタムフィールド表示側の実装

ブログのカスタムフィールドで行った事の繰り返しになりますが、今回はカテゴリーになりますので、利用するモジュールはカテゴリーフィールドを利用します。

<!-- BEGIN_MODULE Category_Field -->

<!-- END_MODULE Category_Field -->

ブログのカスタムフィールドと同様なので、以下 HTML は見ないで、実装が完了したら答え合わせにご利用ください。

<!-- BEGIN_MODULE Category_Field -->
<div class="page-title-wrapper" style="background-image: url(%{MEDIA_ARCHIVES_DIR}{category-image@path});">
  <div class="page-title-filter"></div>
  <div class="page-title-inner">
    <div class="acms-container">
      <p class="page-title">%{CATEGORY_NAME}</p>
      <!-- BEGIN description:veil -->
      <p class="page-description">{category-description}[nl2br4html]</p>
      <!-- END description:veil -->
    </div>
  </div>
</div>
<!-- END_MODULE Category_Field -->

今回、見慣れない [nl2br] という記述が見つかります。 これは a-blog cms の機能で、校正オプション と呼びます。{変数}の値を利用し情報を編集するようなプログラムを実行することができます。


{category-description}[nl2br4html] と記述することで、{category-description} の改行コードを \<br> に置き換える処理を行います。

カテゴリー「採用情報」カスタム設定 から、データを入れることで http://localhost/recruit/ には、以下のような表示となります。



まとめ

今回はカスタムフィールドを中心に、テンプレートで使う機能を紹介しました。

  • ブログのカスタムフィールドでヘッダー・フッターの編集
  • カテゴリーのカスタムフィールドでカテゴリーヘッダーの編集
  • 条件分岐をするための IFブロックや :veilブロックの紹介
  • グローバル変数の利用
  • 校正オプションの利用

それらしくなってきましたが、まだまだな部分もあります。 その3「モジュール編」 で、さらに完成度を高めていきます!

Twitterで「カスタムフィールド編」完了をシェアする