01ブロックに module を表示する
想定しているのは、最新記事とカテゴリ一覧ですが、考え方としては、
- ビューレンダー時に、タイプ module のブロックがきたら、別ファイルとして用意したモジュールファイル latest_articles.blade.php (categories_list.blade.php) を @include する
- モジュールファイルは、ビューコンポーサーという機能を使ってデータと結びつけておく
- ビューコンポーサーは、app/composers.php にまとめて定義し、app/start/global.php で require する
(参考)Laravel4でView Composerの設定をする場所 – atijust’s blog
これでなんとかいけそうですが、その前に、ブロックの登録、保存も少し見直した方がよさそうです。
- ブロックのタイプ名見直し
content -> static、module -> dynamic - 要素 textarea の name 属性変更、および blocks テーブルのカラム名変更
value -> contents - タイプ dynamic は、保存されたモジュールファイル名からリストを作成し、select 要素で選択できるようにする
- ブロック作成の初期ページでは、select、textarea ともに非表示とし、タイプ選択 radio をクリックした場合に、該当要素を表示する
- ブロックのタイプにかかわらず、内容は、blocks テーブルの contents に保存する
blocks テーブルのカラム名変更
Schema::table(‘blocks’, function($table)
{
$table->renameColumn(‘value’, ‘contents’);
});
でいけますが、その前に doctrine/dbal を入れておく必要があるようです。composer.json に
“doctrine/dbal”: “2.3.5”
を追加して
$ composer update
$ php artisan migrate
とすれば、カラム value が contents に変更されます。app/models/Block.php のバリデーションルールも変更しておく必要があります。
モジュールリストをファイル一覧から取得する
モジュールリストの作成には新しいクラスを作った方がよさそうです。モジュールのビューファイルは、app/views/modules に置くこととして、
class Helpers {
const MODULE_PATH = ‘/app/views/modules’;
public static function getModuleNames()
{
$path = base_path() . self::MODULE_PATH;
$files = File::files($path);
foreach($files as $file)
{
$line = fgets(fopen($file, ‘r’));
$m_name = preg_replace(‘/[!-\/:-@≠\[-`{-~]|\r|\n/i’, ”, $line);
$m_file = preg_replace(‘{‘ . $path . ‘/(((?!\.).)*).*$}’, ‘$1’, $file);
$modules[$m_file] = $m_name;
}
return $modules;
}
}
ファイルの一行目には、モジュールの名前を <!—-> でくくって入れておき、正規表現で取りだしています。ファイル名は、ディレクトリからファイル一覧を取得し、こちらも正規表現で必要部分のみ取りだしています。
この際、変数 $path にはエスケープすべき文字 ‘/’ が含まれていますので、当然エラーになってしまいます。どうするんだろうと悩んだんですが、’//’ の代わりに ‘{}’ も使えるんですね。下のサイトを参考にさせていただきました。勉強になります。
preg_match() に変数を入れたら”/”でエラーが出てしまう場合の解決法
で、作成したクラスはどこに置けばいいんだろう?ということですが、composer のオートロードを利用すればいいようです。
自作のクラスを app/helpers.php として保存、composer.json に
“autoload”: {
“classmap”: [
(略)
],
“files”: [
“app/helpers.php”
]
},
files 以下を追加し、$ composer dump-autoload を実行すれば使えるようになります。
バックエンド/ブロック新規作成、編集の変更
コードは ausnichts/laravel4-blog · GitHub にあります。新規作成の初期画面は、
タイプ static をクリックすると、
タイプ dynamic をクリックすると、
となります。jquery の slideUp()、slideDown() を使っています。
で、結構苦労したのが、dynamic の場合に select の値を contents に代入する方法です。textarea の値を取り出したり、代入しようとしても全く反映されません。
原因は CKEditor でした。
CKEDITOR.instances.editor.getData()
CKEDITOR.instances.editor.setData()
を使わないと操作できないことが分かりました。
ビューコンポーサー
app/composers.php
View::composer(‘modules.latest_articles’, function($view) {
$view->latest_articles = Article::where(‘is_published’, TRUE)->orderBy(‘published_at’, ‘DESC’)->take(5)->get();
});
View::composer(‘modules.categories_list’, function($view) {
$view->categories_list = Category::all();
});
最新記事の表示数も行く行く変更できるようにしたいですね。
モジュールビューファイル
app/views/modules/categories_list.blade.php
<!–Display Categories–>
<ul>
@foreach($categories_list as $category)
<li><a href=”{{ URL::to(‘category-index’, array(‘id’=>$category->id)) }}”>{{ $category->category }}</a></p>
@endforeach
</ul>
app/views/modules/latest_articles.blade.php
<!–Latest Articles–>
<ul>
@foreach($latest_articles as $article)
<li><a href=”{{ URL::to(‘article’, array(‘id’=>$article->id)) }}”>{{ $article->title }}</a></li>
@endforeach
</ul>
index.blade.php など、ビューファイルの sidebar 部分
@foreach($blocks as $block)
<div class=”sidebar-module sidebar-module-inset”>
@if($block->type)
<h4>{{ $block->title }}</h4>
@include(‘modules.’ . $block->contents)
@else
<h4>{{ $block->title }}</h4>
{{ $block->contents }}
@endif
</div>
@endforeach
ということで、こんな感じになりました。
css がオリジナルのままなので見た目は良くありませんが、まあなんとかブログらしくなってきました。後は、ブログタイトルなどの設定画面で変更できるようにしたいですね。