Ver.2.12より、管理画面、及び全てのテーマで Dart Sass に移行します


いつも a-blog cms をご利用いただき、誠にありがとうございます。開発スタッフの森田です。

Ver.2.12より、管理画面、及び全てのテーマで Dart Sass に移行することになったため、経緯と以降の方法をお知らせいたします。
なお、現在CSSからスタイルをカスタマイズされている方々は以前と同じようにカスタマイズできますので、ご安心ください。この記事は今までSassを使ってカスタマイズされていた方々を対象に、具体的な実装をご案内しています。

なぜ Dart Sass へ移行するのか

公式ブログのFuture Plansの項目にて、LibSass のサポートは遅くとも2022年10月1日には廃止されるというアナウンスがありました。


Sassが@importを非推奨とすることと、新しいSassの機能を使用していくため a-blog cms の開発においても Dart Sass へ移行をおこないます。

ご利用中のテーマではそのままLibSassをお使いいただくことも可能ですが、新しいバージョンの a-blog cms 内のSassを使用時には記述がDart Sassに対応されていることと、今後Sassの公式でもDart Sassがメインになっていくことを考え、早めの移行をお勧めいたします。

移行時の変更

主な変更内容は @import ルールを使用していた箇所が @use及び@forwardへの変更になります。

これにより以下の作業が想定されます。

  • Mixinや変数、関数の重複を回避する
  • ファイル名が重複する場合は名前空間の指定

Mixinsや変数、関数を使用している際には移行する際に多少作業が必要になりますので、その点はご留意ください。

@useとは

@useルールは、他のSassスタイルシートからMixins、関数、変数を読み込むことができ、複数のスタイルシートのCSSをまとめて表示する機能です。

@useで読み込まれたメンバー(変数、関数、Mixins)は、カプセル化され読み込んだスタイルシートでのみ使用できます。

シンプルに利用する際には @use "<url>" のように記述して利用します。

// _variables.scssを読み込むときの例

@use "variables";

ファイル名で読み込んだ際は、そのファイル名が名前空間となります。そのため、以下のように使用できます。

@use "variables";

.button {
  color: variable.button-color;
}

名前空間はas節を使用して変更可能です。

@use "variables" as var;

.button {
  color: var.button-color;
}

変数がグローバルでは無くなったことにより、同じ変数名や、関数名、Mixins名を使用して上書きできなくなリました。

外部から変数を変更したい場合は、あらかじめ上書きできるようにしたい箇所に !default フラグを指定しておき、@useで読み込む際にwith節を使用して変更します。

// variables.scss

$button-color: red;

.button {
  background: $button-color !default;
}

@use "variables" with (
  $button-color: blue
)

詳しくは公式ドキュメントをご覧ください。


@forwardとは

@useでは読み込んだ変数やMixinsなどのメンバーしか読み込めませんが、@useルールと異なる点としては、階層の深いファイルで指定したメンバーも読み込むことができ、利用時には単一のエントリーポイントのファイルを読み込むことができます。

シンプルに利用する際には @forward "<url>" と記述して利用します。

// エントリーポイントのファイル global/common.scss

@forward "variables";
@forward "mixins";
@forward "functions";
@use "../global/common"

.button {
	background: $button-color; //コンパイルエラーになる
}
@forward "../global/common"

.button {
	background: $button-color; //コンパイルできる
}

@forwardを利用の際にもwith節を使用して外部から内容を変更することができます。

@forward "../global/common" with (
  $button-color: blue;
)

.button {
	background: $button-color; //blueが出力される
}

実際にa-blog cms のテーマ内で使用している記述では、acms.cssの内容を変更する際には下記のように利用します。

@forward "../../../../system/src/scss/global/variables" with (
    $unit-gutter : 20px,
    $entry-class : entry-style,
    $unit-margin-bottom : 30px,
    $acms-font: '../../../system/fonts/'
);

同じ変数名が存在するとエラーが起こるので、もし$unit-gutterなどを変数名で別途上書きをしている場合は、その記述を削除し、with節で変更内容を指定しましょう。

詳しくは公式ドキュメントをご覧ください。


移行手順

実際に、Site2020を移行した手順をご紹介します。

  • Dart Sassへコンパイルするための環境を用意する
  • ルートのscssファイルをforwardとuseで読み込む
  • forwardで読み込んだ変数、関数、Mixinを整える
  • useで読み込んでいるファイルに名前空間を反映する

Dart Sassへコンパイルするための環境を用意する

gulp、webpackなどでコンパイルする際は、node-sass モジュールではなく、 sass モジュールを使用してください。

$ npm i sass --save-dev

ルートのscssファイルを@forwardと@useで読み込む

// site.scss

@charset "utf-8";

// グローバルメンバーファイル acms.css兼用
@forward "global/acms-common";

// グローバルメンバーファイル siteテーマ専用
@forward "global/common";

// ベース
@use "base";

// パーツ
@use "animation";
@use "banner";
@use "button";

... 以下省略 ...

@importを使用時は変数やMixins、コンポーネント利用時にも利用していましたが、ここでは変数やMixins、関数は@forward、コンポーネントは@useを使用しています。

forwardで読み込む変数、関数、Mixinsを整える

a-blog cms の公式テーマでは、変数、関数、Mixins は全てのコンポーネントのファイルで参照しているファイルです。これらをまとめるacms-common.scssとcommon.scssを作成しています。

公式テーマではglobalディレクトリを新しく作り、下記のように設定しています。

  • global/_acms-common.scss
  • global/_common.scss
  • global/mixins.scss
  • global/variables.scss
// global/_acms-common.scss

@forward "../../../../system/src/scss/global/variables" with (
    $unit-gutter : 20px,
    $entry-class : entry-style,
    $unit-margin-bottom : 30px,
    $acms-font: '../../../system/fonts/'
);
@forward "../../../../system/src/scss/global/variables-fonts";
@forward "../../../../system/src/scss/global/mixins";
// global/common.scss

@forward "variables";
@forward "mixins";

Siteテーマの場合は、global/_mixins.scssでacms.cssの変数とMixinsを使用しています。そのため、ファイルの先頭に@useを使ってacms-common.scssを読み込んでいます。

こうすることによって、systemテーマ内のmixins.scssで指定しているfont-sizeのMixinsが利用可能になります。

// global/_mixins.scss

@use "../global/acms-common" as acms;

@mixin footer-sns-list($sns-color){
	... 省略 ...
	@include acms.font-size(19);
  ... 省略 ...
}

useで読み込んでいるファイルに名前空間を反映する

公式テーマでは、acms.cssの変数、関数、Mixinsに加えて、テーマが各自で持っている変数、関数、Mixinsを使用します。

どのファイルの変数、関数、Mixinsを使用しているのかわかりやすくするために名前空間を指定しています。

コンポーネントのファイルの先頭にて、@useでファイルを名前空間を指定して読み込みます。

以下の場合は、acms-common.scssのメンバーはacms、common.scssのメンバーはglobalという名前空間が割り振られています。

// scss/_base.scss
@use "global/acms-common" as acms;
@use "global/common" as global;

LibSass利用時は以下のような記述でしたが、この記述ではエラーが出てしまいます。さらに名前空間を指定する必要があります。

// LibSass利用時の記述
@use "global/acms-common" as acms;
@use "global/common" as global;

body {
	color: $text-color-base;
	font-family: $font-family;
	background: #FFF;
	@include font-size(14);
}

名前空間を指定した記述が以下になります。

// Dart Sass利用時の記述
@use "global/acms-common" as acms;
@use "global/common" as global;

body {
	color: global.$text-color-base;
	font-family: global.$font-family;
	background: #FFF;
	@include acms.font-size(14);
}

global.xxxacms.xxx という記述が増えました。$text-color-base はglobal/_common.scss で指定したファイルから参照しており、名前空間をasglobalと指定しているのでglobal.xxx@include font-size(); はglobal/acms-commonから指定したファイルから参照しており、名前空間をasacmsと指定しているのでacms.xxx を指定します。

ユニットのガターなどはsystemフォルダの変数を利用しているケースがあるかと思いますが、その時は以下のようにwith節を使用して@forward時に変数の内容を変更してください。

// global/_acms-common.scss

@forward "../../../../system/src/scss/global/variables" with (
    $unit-gutter : 30px,
    $entry-class : entry-style,
    $unit-margin-bottom : 30px,
    $acms-font: '../../../system/fonts/'
);
@forward "../../../../system/src/scss/global/variables-fonts";
@forward "../../../../system/src/scss/global/mixins";

acms.cssでは、$entry-class はacms-entryが指定されていますが、上記の記述ではentry-styleに変更しています。

まとめ

これらの変更はVer.2.12の各テーマおよび管理画面にて行う予定です。リリースまで今しばらくお待ちください。

また、Ver.2.12からはWebpackでコンパイルできる環境を各テーマで用意する予定です。nodeをマシンにインストールされている方であればターミナルまたはコマンドプロンプトに $ npm i とするだけで、テーマのスタイル、JSがコンパイルできます。

Ver.2.12についての詳しい情報は、9月10日、9月11日に行われる a-blog cms Training Camp 2021 Autumn にて公開する予定です。ご興味ある方は是非ご参加ください。


Ver.2.7.0以上へのアップデート

Ver. 2.7.0 未満からのアップデートでの注意点になります。

グローバルルールのコンフィグ設定の仕様が変更になりました。

仕様の違い

Ver. 2.7.0 未満 でのグローバルルールの仕様

  • グローバルルールに設定した場合は、子ブログでもグローバルルールが存在するブログのコンフィグを参照
  • 子ブログ毎にグローバルルールの設定はそれぞれ出来ない。

Ver. 2.7.0 以上 でのグローバルルールの仕様

  • グローバルルールを設定しても、ルールのみグローバルであってコンフィグはグローバル化しない。
  • グローバルルールの設定はそれぞれの子ブログで設定する必要がある。

解決方法

もし、Ver. 2.7.0 未満のバージョンでグローバルルールを使って、全ての子ブログに、グローバルルールがある ブログのコンフィグを利用している場合、バージョンアップすると、コンフィグが子ブログ毎になりうまく動作しません。 そこで、以下方法を行うと後方互換性を持たせる事が出来ます。

config.system.yaml に以下を追記

global_rule_config_load: global
  • global を設定すると Ver. 2.7.0 未満の仕様
  • each(デフォルト)を設定すると Ver. 2.7.0 以上の仕様

ポストインクルードで色々な情報を引っ張ってくる

ポストインクルードを使うことにより、現在表示しているURLとは関係ない情報を好きに引っ張ってくることができます。 モジュールIDを使えば、同じようにURLと関係ない情報を出力することはできるのですが、エントリーの情報を使って、引っ張ってくる値が変わる場合はどは、ポストインクルードが便利です。

例: エントリー詳細ページで、そのエントリーのカスタムフィールドの値を元に、関連する記事一覧を引っ張ってくるなど。

実装方法

POST_2GETモジュールを使用します。POST_2GETモジュールは、POSTデータにa-blog cmsの様々なパラメータを渡して送信すると、そのパラメータを元にURLを組み立て、好きなページを表示できるようになります。(ポストインクルードを使わない場合は、組み立てられたページに移動します)

例: カテゴリーの情報で絞り込み、include/category.html テンプレートを使って表示しています。

<form action="" method="post" class="js-post_include-ready">
  <input type="hidden" name="bid" value="%{BID}" />
  <input type="hidden" name="cid" value="%{CID}" />
  <input type="hidden" name="tpl" value="include/category.html" />
  <input type="submit" name="ACMS_POST_2GET" />
</form>

様々なパラメーター

<!-- ID を指定 IDに沿ったURLが生成されます。 -->
<input type="hidden" name="bid" value="1"> <!-- ブログIDを指定 -->
<input type="hidden" name="aid" value="1"> <!-- エイリアスIDを指定 -->
<input type="hidden" name="uid" value="1"> <!-- ユーザーIDを指定 -->
<input type="hidden" name="cid" value="1"> <!-- カテゴリーIDを指定 -->
<input type="hidden" name="eid" value="1"> <!-- エントリーIDを指定 -->
<input type="hidden" name="cmid" value="1"> <!-- コメントIDを指定 -->

<!-- キーワードを指定 -->
<input type="text" name="keyword" value="%{KEYWORD}">

<!-- タグを指定 -->
<input type="hidden" name="tag" value="aaa">

<!-- フィールドを指定 -->
<input type="hidden" name="hoge" value="aaa">
<input type="hidden" name="field[]" value="hoge">

<!-- 表示順を指定 -->
<!-- 日時 ( 昇順 ) -->
<input type="hidden" name="order" value="datetime-asc">
<!-- 日時 ( 降順 ) -->
<input type="hidden" name="order" value="datetime-desc">
<!-- ファイル名 ( 昇順 ) -->
<input type="hidden" name="order" value="code-asc">
<!-- ファイル名 ( 降順 ) -->
<input type="hidden" name="order" value="code-desc">
<!-- ID ( 昇順 ) -->
<input type="hidden" name="order" value="id-asc">
<!-- ID ( 降順 ) -->
<input type="hidden" name="order" value="id-desc">
<!-- 表示順 ( 昇順 ) -->
<input type="hidden" name="order" value="sort-asc">
<!-- 表示順 ( 降順 ) -->
<input type="hidden" name="order" value="sort-desc">
<!-- フィールド ( 昇順 ) -->
<input type="hidden" name="order" value="field-asc">
<!-- フィールド ( 降順 ) -->
<input type="hidden" name="order" value="field-desc">
<!-- 数値フィールド ( 昇順 )	 -->
<input type="hidden" name="order" value="intfield-asc">
<!-- 数値フィールド ( 降順 ) -->
<input type="hidden" name="order" value="intfield-desc">
<!-- ランダム -->
<input type="hidden" name="order" value="random">

<!-- テンプレートを指定 -->
<input type="hidden" name="tpl" value="/include/sample.html">

<!-- ページを指定 -->
<input type="hidden" name="page" value="3">

<!-- 表示数を指定 -->
<input type="hidden" name="limit" value="50">

<!-- 期間を指定 -->
<input type="hidden" name="start" value="2014-01-01">
<input type="hidden" name="span" value="span">
<input type="hidden" name="end" value="2015-12-31">

<!-- 日付を指定 -->
<input type="hidden" name="date" value="2015-12">

<!-- クエリストリングを指定 ?key1=aaa&key2=bbb-->
<input type="hidden" name="key1" value="aaa">
<input type="hidden" name="key2" value="bbb">
<input type="hidden" name="query[]" value="key1">
<input type="hidden" name="query[]" value="key2">

このようなパラメータを使うことにより好きなページの情報を取得することができるようになります。 実装に困った時は、一度ポストインクルードで出来ないか検討してみてください。