前回、sitemap.jsonを読み込めるようプログラミングしました。今回はそのデータをHTMLタグに当てはめていきます。
今一度assets/template/nav.html
を確認してみましょう。この中でデータによって生成される部分と、固定部分を見分けます。
<!-- PageHeader --> <!-- /PageHeader -->
メニューバー全体を構成するブロックは、変わりませんね。その中で、9行めの%s
部分がデータによって生成されます。ですので、このブロック部分をテンプレートとして、変数に格納します。
function navHeader(){ $tempNavBarBlock = <<<DOC <!-- PageHeader --> <!-- /PageHeader --> DOC;
%s
部分に入るタグには幾つかパターンが見受けられます。(%s
については後で解説します。)「Homeや売上管理」がある、第1階層の要素にはchild
要素がある要素とない要素があります。
child
要素がない場合に生成するHTML
child
要素がある場合に生成するHTML
そして、各Link要素はすべて<li><a href=""></a></li>
となっています。よく見るとchild要素がない場合もこのパターンに当てはまります。ということで下記のパターンを抽出できます。
この二つのテンプレートを変数$tempNavBarBlock
の次に記述しておきます。
foreach()
に戻りましょう。メニューデータにはchild
のあるものないもので、生成するHTMLタグを振り分けることが必要でした。それをforeach()
に記述してみましょう。
foreach($navData as $obj){ if(isset($obj->child)){ } else{ } }
このような条件ブロックが書けます。今度は、それぞれのブロックで生成したタグを格納しておくための入れ物が必要ですね。ここでは配列を使って入れ物としましょう。変数はforeachの上で初期化します。
$navItems = []; foreach($navData as $obj){ }
変数$navItems
の値に[]
を代入しています。これで、この変数には配列データとして初期化したことになります。この配列にデータを追加していくには、
パターン1 : $navItems[] = 'a'; $navItems[] = 'b'; パターン2 : array_push($navItems, 'a');
など複数の書き方があります。また、配列の後ろに値を追加してくか、前に追加していくかなど様々な関数が用意されています。ここでは、パターン1の書き方にします。記述が簡潔に見えるからです。
それでは、まずchild
がない場合を追記してみましょう。
foreach($navData as $obj){ if(isset($obj->child)){ } else{ $navItems[] = sprintf($tempLink, $obj->url, $obj->name); } }
何やらまた新しい関数が出てきました。
これはフォーマット文字列内に書かれている%s
や%d
を第2以降の引数で変換するというものです。%s
のように%アルファベット
のことを指示子(ディレクティブ)と言います。テンプレート中にか書かれている指示子の数と順番が引数の数と順番が一致している必要があります。
例えば $format = 'この%sは%d円です。'; echo sprintf($format, '本', 2000);
文字列を生成する際にこのようにフォーマットを用意し、それに値を当てはめていく方法と、順番に文字列を連結していく方法があります。
$name= '本'; $price = 2000; echo 'この' . $name . 'は' . $price . '円です。';
連結方法は、ほんの短い文字列であれば問題ありませんが、複雑になってくると最終的にどういうものを作りたいのかが見えにくくなります。最終成果物を見通しやすいことからフォーマット方法をお勧めします。
続いて、child
がある場合を追記します。
if(isset($obj->child)){ $navChildItems = []; foreach($obj->child as $childObj){ $navChildItems[] = sprintf($tempLink, $childObj->url, $childObj->name); } $navItems[] = sprintf($tmpChildBlock, $obj->name, implode("\n", $navChildItems)); }
child
の子要素分のLinkタグを生成し、それらを$tmpChildBlock
に当てはめたものを$navItems
に追加します。ここでも新しい関数が出てきました。
これは配列データを連結して一つの文字列に変換する命令です。第1引数が連結文字列です。ここでは改行コードで連結しています。この第1引数を省略すると、カンマで連結されます。CSVを作成する際には第1引数を省略しても構いません。
これで、メニューの各要素が出来当たりました。最終段階です。最初に作成したテンプレレート$tempNavBarBlock
に当てはめます。関数navHeader
の最後に下記を追記します。
return sprintf($tempNavBarBlock, implode("\n", $navItems));
関数navHeader()
全体を示します。
function navHeader(){ $tempNavBarBlock = <<<DOC DOC; $tempLink = "
今度は、index.php
からこの関数を呼び出しましょう。
<?php require_once('../includes/classes/AppMasterHtml.php'); ?> <?= AppMasterHtml::htmlHeader() ?> <?= navHeader() ?>
メニューバーが表示されるはずです。
次回はこの関数にエラー処理を入れてみましょう。