ブレッドクラム パスはどこで宣言する必要がありますか (つまり、MVC のどの文字で)? これまでは Controllers で宣言していましたが、最近 CakePHP を使い始めました。CakePHP ではすべて Views で作成されており、驚きました。
5 に答える
ブレッドクラムで何をすべきか、何をすべきでないかについて多くの混乱があるため、ここで回答を投げかけます。
モデル
モデルは、ドメイン オブジェクト、データ マッパー、およびサービスで構成されるビジネス ロジックを含むレイヤーです。モデルの詳細については、こちらをご覧ください。
コントローラー
覚えておいてください:ファット モデル、スキニー コントローラー. コントローラー/メソッドは、ルーティング メカニズムからアクセスされます。コントローラーに入ったら、モデル オブジェクトを取得し、モデルで必要なロジックを実行し、その結果をコントローラーの変数に返してから、これを使用してビューにデータを表示します。
ブレッドクラム
そうは言っても、パンくずリストが機能するにはさまざまな部分が必要です。これについて考えてみましょう:
- 彼らは現在のページを必要としています
- ページのリストが必要です
- カスタムの「class=current」を追加する必要がある場合があります
それらを分解する:
- 私のフレームワークでは、現在のコントローラーはページ名でもあります (ログイン コントローラーは /login にマップされます)。したがって、すでに現在のページがあります。
- ページのリスト。
- ページの親子関係がdatamodelに直接結び付けられている場合、コントローラーでモデルからページのリストを取得します。したがって、ブレッドクラムを自動生成できる場合はモデルを使用してください。
- 使用しているフレームワークで、ユーザーの選択だけでブレッドクラムを作成できる場合は、ブレッドクラムに何を入れるかを手動で選択しているだけです。いずれにせよ、パンくずリストをコントローラーに記述し、どこかから取得する必要がある場合は、モデルを使用します。
- 最後に、「class=current」です。ビューに重要な「ロジック」を実際に含める必要はありませんが、ループや if ステートメントなどの小さなものはかなり標準的です。ここで、ブレッドクラムで現在のコントローラー名 (変数としてビューに渡される) と同じタイトルを確認し、
class=current
見つかった場合は a を追加します。
コード例
注: 未テスト
/**
* So we're in the home controller, and index action
*
* @route localhost/home or localhost/home/index
* (depending on .htaccess, routing mechanism etc)
*/
class Home extends Controller
{
public function index()
{
// Get current class name, so we have the current page
$class = __CLASS__;
// Let's say the page heirachy is tied to the model, so get pages for current method, or however you want to implement it
$pages = $model->getPages($class);
// So the TEMPLATE handles the breadcrumbs creation, and the controller passes it the data that it needs, retrieved from the model
// (new Template) is PHP 5.4's constructor dereferencing, also included is some lovely method chaining
// setBreadcrumbs() would assign variables to the view
// Render would do just that
(new Template)->setBreadcrumbs($currentPage, $pages)->render();
}
}
そして今、ビュー...メモ、私はPHP 5.4を使用しているので、短いエコーを使用できます...
<body>
<?php foreach($breadcrumbs as $b) { ?>
<li <?=($b['current'])?'class="current"':''?>>
<a href="<?=$b['page']['url']?>">
<?=$b['page']['title']?>
</a>
</li>
<?php } ?>
</body>
そして、それが私がそれをする方法です。これのいくつかは個人的な好みによるものですが、これが 1 つの方法を示し、少なくとも少しは役立つことを願っています。
私は実際にこの答えをグーグルで「php mvc パンくずリスト」に出くわしました。私の脳を書き出すことは、これを理解するのにも本当に役立ちました。ほんとありがと!
「ロジック」と「ビュー」という言葉を一緒に見るたびに、心配し始める必要があります。ブレッドクラムはアプリケーションレベルのロジックの典型的な例であるため、コントローラーに投票します。ビューに配置すると、私の意見では MVC に違反します。
ブレッドクラムはコントローラーにある必要があります。私はCodeIgniterを使用し、次のようなことをします
$data['breadcrumb'][0] = array("title" => "Home", "alt" => "Home Page", "path" => "home/");
$data['breadcrumb'][1] = array("title" => "About", "alt" => "About Me", "path" => "home/about");
次に、ビューでループしてリストとして表示します。
<ul class="breadcrumbs">
foreach($breadcrumb as $b)
{
?>
<li><a href="<?php echo base_url(); ?>index.php/<?php echo $b['path'];?>" alt="<?php echo $b['alt']; ?>"><?php echo $b['title']; ?></a></li>
<?php
}
</ul>
その後、クラスや現在のページなどの単純なものを宣言することもできます。唯一の欠点は、すべてのページにブレッドクラムを設定する必要があることです。
すべてのロジックはコントローラーにある必要があります。モデルを介してデータベースにアクセスし、コントローラーでロジックを実行して、それをビューに渡します。
のような単純なもの
<?php echo ($loggedin)?"Logged in as" . $user->firstname:"Not logged in";?>
ビューに入ることができます。ただし、複雑なフロー パターンを設定するべきではありません。そこはコントローラーにお任せください。ビューは安いです。わずかに異なるビューを半ダース表示することができ、誰も気にしません。半ダースのページを維持しなければならない静的 HTML とは異なります。
ビューに共通のもの (ヘッダー、フッター、スクリプト ファイル、javascript ファイルなど) を含めてから、そのままにしておきます。
IMO、ブレッドクラムは、解釈に応じて、現在のページまたはサイトの階層内のアクションの場所に到達するために実行される一連のコントローラー アクションに関連しています。その観点からすると、コントローラはデータを構築する自然な場所のように見えますが、レンダリングはビューで行われる必要があります。ビューで完全に生成されるようにするには、ビューによって呼び出されているコントローラー アクションに関する詳細を公開するか、アクションごとのビュー モデルを固定して、それぞれのブレッドクラムを事前に計算できるようにする必要があります。ブレッドクラムを計算するためのロジックをビュー自体に移動することは、MVC での関心の分離に違反しているようであり、DRY に違反するさまざまなアクションでビューを再利用できなくなる可能性があります。
私の意見では、ブレッドクラムのデータを生成することはコントローラーの分野横断的な問題です。つまり、URL を使用してブレッドクラム データを構築するアクションに関係なく実行される共有コードがあります。また、コントローラーが提供するデータを受け取り、それをデザインと一致させる共有ビュー コードもあります。
私が純粋に建築的な観点から話していることに注意してください。私はCakePHP(または他のPHPフレームワーク)に精通しておらず、それについてのあなたの観察が正しいかどうかを判断することさえできません. パターンの観点からは、コントローラーに入れるのが正しいことのように思えます。ただし、特定の実装では、パターンに違反することが理にかなっている場合があります。
$this->Html->addCrumb('Home', '/pages/home');
$this->Html->addCrumb('Contacts', '/pages/contacts');
echo $this->Html->getCrumbs('»', 'StartText');