APIをPHPで取得して、HTMLで出力する、というお仕事がありました。
APIで取得できるデータは「日付・タイトル・リンク情報」です。ニュース情報なので同じ日付も入ってきます。出力するHTMLデータはこちら。APIは取得済みですでに配列化されているものとします。
$data = array();
$data[] = array( 'date'=>'2018-8-12', 'title'=>'サンプルタイトル1', 'link'=>'https://ippaiattena.co.jp/' );
$data[] = array( 'date'=>'2018-8-13', 'title'=>'サンプルタイトル2', 'link'=>'https://ippaiattena.co.jp/' );
$data[] = array( 'date'=>'2018-8-14', 'title'=>'サンプルタイトル3', 'link'=>'https://ippaiattena.co.jp/' );
$data[] = array( 'date'=>'2018-8-14', 'title'=>'サンプルタイトル4', 'link'=>'https://ippaiattena.co.jp/' );
$data[] = array( 'date'=>'2018-8-15', 'title'=>'サンプルタイトル5', 'link'=>'https://ippaiattena.co.jp/' );
<ul>
<li>
<dl>
<dt>
<time>8/13</time>
</dt>
<dd>
<a href="〜">リンク先</a>
</dd>
</dl>
</li>
<li>
<dl>
<dt>
<time>8/14</time>
</dt>
<dd>
<a href="〜">リンク先</a>
</dd>
<dd>
<a href="〜">リンク先</a>
</dd>
</dl>
</li>
<li>
<dl>
<dt>
<time>8/15</time>
</dt>
<dd>
<a href="〜">リンク先</a>
</dd>
</dl>
</li>
....
</ul>
ネックは、データでは同一の日付も別データなのに、デザインだと同ブロックで表示されていることですね。最初こんな風に書いてみました。
<?php
$prev = new DateTime( ('2018-8-1') );
$html = array();
foreach ( $data as $row ) {
// 対象の日付を取得
$today = new DateTime( $row['date'] );
echo '<li><dl>';
// 前回の値と同一の日付かチェック。同一の日付でなかった場合
if ( $prev < $today ) {
echo '<dt><time>' . $today->format( 'n/j' ) . '</time></dt>';
echo '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
}
// 同一の日付であった場合
else {
echo '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
}
echo '</dl></li>';
// 次ループの為に確保
$prev = $today;
}
?>
やっぱりうまく行きません笑
まあ、最初の1回でうまく行くなら誰も仕事で困らない!
まず文字列を扱いやすいように即出力ではなくて配列にしました。
次のループが同一の日付の場合は<li><dl>を閉じたくなくて、次のループが別の日の場合は<li><dl>を閉じたい。。でも、次のループの日付は、次のループに進まないと分からない。。
試行錯誤の末、こんな感じになりました。
<?php
$prev = new DateTime( ('2018-8-1') );
$html = array();
foreach ( $data as $row ) {
$today = new DateTime( $row['date'] );
// 前回の値と同一の日付かチェック。同一の日付でなかった場合
if ( $prev < $today ) {
$html[] = '</dl></li>'; // ←ポイント
$html[] = '<li><dl>';
$html[] = '<dt><time>' . $today->format( 'n/j' ) . '</time></dt>';
$html[] = '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
}
// 同一の日付であった場合
else {
$html[] = '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
}
$prev = $today;
}
// 足りない分補足
$html[] = '</dl></li>';
// 余計な分削除
array_shift( $html );
// 出力
echo '<ul>' . implode( "n", $html ) . '</ul>' . "n";
?>
できました〜\(^o^)/
でも、絶妙に「足りない分補足」「余計な分削除」がイケてない。。
もうちょっとごにょごにょして、最終的にこの形になりました。
<?php
$prev = new DateTime( ('2018-8-1') );
$html = array();
foreach ( $data as $row ) {
$today = new DateTime( $row['date'] );
// 前回の値と同一の日付かチェック。同一の日付でなかった場合
if ( $prev < $today ) {
$html[] = '<li><dl>';
$html[] = '<dt><time>' . $today->format( 'n/j' ) . '</time></dt>';
$html[] = '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
$html[] = '</dl></li>';
}
// 同一の日付であった場合
else {
array_pop( $html ); // ←ポイント①
$html[] = '<dd><a href="' . $row['link'] . '">リンク先</a></dd>';
$html[] = '</dl></li>'; // ←ポイント②
}
$prev = $today;
}
echo '<ul>' . implode( "n", $html ) . '</ul>' . "n";
?>
すっきり〜\(^o^)/
PHPとHTMLの結合は、ほんとうにパズルですね。