URLリンクの作成
Netteでリンクを作成するのは、指をさすのと同じくらい簡単です。指し示すだけで、フレームワークがすべての作業を代行します。ここでは以下について説明します。
- テンプレートやその他の場所でリンクを作成する方法
- 現在のページへのリンクを区別する方法
- 不正なリンクの対処法
双方向ルーティングのおかげで、後で変更される可能性のあるアプリケーションのURLをテンプレートやコードにハードコーディングしたり、複雑に組み立てたりする必要は決してありません。リンクでPresenterとアクションを指定し、必要に応じてパラメータを渡すだけで、フレームワークがURLを自動的に生成します。実際には、関数を呼び出すのと非常によく似ています。これは気に入るはずです。
Presenterテンプレート内
最も頻繁にリンクを作成するのはテンプレートであり、n:href
属性は素晴らしいヘルパーです。
<a n:href="Product:show">詳細</a>
HTML属性 href
の代わりに、n:属性
n:href
を使用していることに注意してください。その値は、href
属性の場合のようにURLではなく、Presenterとアクションの名前です。
リンクをクリックすることは、簡単に言えば、ProductPresenter::renderShow()
メソッドを呼び出すようなものです。そして、そのシグネチャにパラメータがある場合は、引数を付けて呼び出すことができます。
<a n:href="Product:show $product->id, $product->slug">製品詳細</a>
名前付きパラメータを渡すことも可能です。次のリンクは、値 cs
を持つ
lang
パラメータを渡します。
<a n:href="Product:show $product->id, lang: cs">製品詳細</a>
ProductPresenter::renderShow()
メソッドがそのシグネチャに $lang
を持っていない場合、$lang = $this->getParameter('lang')
を使用してパラメータの値を取得するか、プロパティから取得できます。
パラメータが配列に格納されている場合、...
演算子(Latte 2.xでは (expand)
演算子)を使用して展開できます。
{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">製品詳細</a>
リンクでは、いわゆるパーシステントパラメータも自動的に渡されます。
n:href
属性はHTMLタグ <a>
に非常に便利です。リンクを他の場所、例えばテキスト内に出力したい場合は、{link}
を使用します。
アドレスは: {link Home:default}
コード内
Presenterでリンクを作成するには、link()
メソッドを使用します。
$url = $this->link('Product:show', $product->id);
パラメータは、名前付きパラメータを含めることができる配列を使用して渡すこともできます。
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
リンクはPresenterなしでも作成できます。そのためにLinkGeneratorとその
link()
メソッドがあります。
Presenterへのリンク
リンクのターゲットがPresenterとアクションの場合、構文は次のようになります。
[//] [[[[:]module:]presenter:]action | this] [#fragment]
この形式は、すべてのLatteタグと、リンクを扱うすべてのPresenterメソッド(n:href
,
{link}
, {plink}
, link()
, lazyLink()
, isLinkCurrent()
,
redirect()
, redirectPermanent()
, forward()
, canonicalize()
、およびLinkGenerator)でサポートされています。したがって、例で n:href
が使用されていても、これらの関数のいずれかを使用できます。
したがって、基本形式は Presenter:action
です。
<a n:href="Home:default">ホームページ</a>
現在のPresenterのアクションにリンクする場合、その名前を省略できます。
<a n:href="default">ホームページ</a>
ターゲットが default
アクションの場合、省略できますが、コロンは残す必要があります。
<a n:href="Home:">ホームページ</a>
リンクは他のモジュールにも向かうことができます。ここでは、リンクはネストされたサブモジュールへの相対リンク、または絶対リンクに区別されます。原理はディスク上のパスに似ていますが、スラッシュの代わりにコロンが使用されます。現在のPresenterが
Front
モジュールの一部であると仮定すると、次のように記述します。
<a n:href="Shop:Product:show">Front:Shop:Product:show へのリンク</a>
<a n:href=":Admin:Product:show">Admin:Product:show へのリンク</a>
特別なケースは、自分自身へのリンクで、ターゲットとして
this
を指定します。
<a n:href="this">更新</a>
ハッシュマーク #
の後のいわゆるフラグメントを介して、ページの特定の部分にリンクできます。
<a n:href="Home:#main">Home:default とフラグメント #main へのリンク</a>
絶対パス
link()
または n:href
を使用して生成されたリンクは常に絶対パス(つまり、/
文字で始まる)ですが、https://domain
のようなプロトコルとドメインを持つ絶対URLではありません。
絶対URLを生成するには、先頭に2つのスラッシュを追加します(例:n:href="//Home:"
)。または、$this->absoluteUrls = true
を設定して、Presenterが絶対リンクのみを生成するように切り替えることもできます。
現在のページへのリンク
ターゲット this
は現在のページへのリンクを作成します。
<a n:href="this">更新</a>
同時に、action<Action>()
または render<View>()
メソッドのシグネチャで指定されたすべてのパラメータも転送されます(action<Action>()
が定義されていない場合)。したがって、Product:show
ページで id: 123
の場合、this
へのリンクもこのパラメータを渡します。
もちろん、パラメータを直接指定することも可能です。
<a n:href="this refresh: 1">更新</a>
isLinkCurrent()
関数は、リンクのターゲットが現在のページと同じかどうかを判断します。これは、例えばテンプレートでリンクを区別するためなどに使用できます。
パラメータは link()
メソッドと同じですが、さらに特定のアクションの代わりにワイルドカード *
を指定できます。これは、そのPresenterの任意のアクションを意味します。
{if !isLinkCurrent('Admin:login')}
<a n:href="Admin:login">ログイン</a>
{/if}
<li n:class="isLinkCurrent('Product:*') ? active">
<a n:href="Product:">...</a>
</li>
1つの要素で n:href
と組み合わせる場合、短縮形を使用できます。
<a n:class="isLinkCurrent() ? active" n:href="Home:">...</a>
ワイルドカード *
はアクションの代わりにのみ使用でき、Presenterの代わりには使用できません。
特定のモジュールまたはそのサブモジュールにいるかどうかを判断するには、isModuleCurrent(moduleName)
メソッドを使用します。
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
シグナルへのリンク
リンクのターゲットはPresenterとアクションだけでなく、シグナル(handle<Signal>()
メソッドを呼び出す)にすることもできます。その場合、構文は次のようになります。
[//] [sub-component:]signal! [#fragment]
したがって、シグナルは感嘆符で区別されます。
<a n:href="click!">シグナル</a>
サブコンポーネント(またはサブサブコンポーネント)のシグナルへのリンクを作成することもできます。
<a n:href="componentName:click!">シグナル</a>
コンポーネント内のリンク
コンポーネントは独立した再利用可能なユニットであり、周囲のPresenterへの依存関係を持つべきではないため、リンクはここで少し異なります。Latte属性
n:href
とタグ {link}
、および link()
などのコンポーネントメソッドは、リンクのターゲットを常にシグナル名と見なします。したがって、感嘆符を指定する必要さえありません。
<a n:href="click">アクションではなくシグナル</a>
コンポーネントテンプレートでPresenterにリンクしたい場合は、{plink}
タグを使用します。
<a href={plink Home:default}>ホーム</a>
またはコードで
$this->getPresenter()->link('Home:default')
エイリアス
Presenter:アクションのペアに覚えやすいエイリアスを割り当てると便利な場合があります。例えば、ホームページ
Front:Home:default
を単に home
と名付けたり、Admin:Dashboard:default
を
admin
と名付けたりします。
エイリアスは、設定の
application › aliases
キーの下で定義されます。
application:
aliases:
home: Front:Home:default
admin: Admin:Dashboard:default
sign: Front:Sign:in
リンクでは、アットマークを使用して記述されます。例えば:
<a n:href="@admin">管理</a>
これらは、redirect()
などのリンクを扱うすべてのメソッドでもサポートされています。
不正なリンク
存在しないPresenterにつながる、ターゲットメソッドがシグネチャで受け入れるよりも多くのパラメータを渡す、またはターゲットアクションのURLを生成できないなどの理由で、不正なリンクを作成することがあります。不正なリンクをどのように処理するかは、静的変数
Presenter::$invalidLinkMode
によって決定されます。これは、これらの値(定数)の組み合わせを取ることができます。
Presenter::InvalidLinkSilent
– サイレントモード、URLとして#
文字が返されますPresenter::InvalidLinkWarning
– E_USER_WARNING 警告がスローされ、本番モードではログに記録されますが、スクリプトの実行は中断されませんPresenter::InvalidLinkTextual
– 視覚的な警告、エラーをリンクに直接出力しますPresenter::InvalidLinkException
– InvalidLinkException 例外がスローされます
デフォルト設定は、本番モードでは InvalidLinkWarning
、開発モードでは
InvalidLinkWarning | InvalidLinkTextual
です。本番環境での InvalidLinkWarning
はスクリプトの実行を中断しませんが、警告はログに記録されます。開発環境では、Tracyによってキャッチされ、ブルースクリーンが表示されます。InvalidLinkTextual
は、#error:
文字で始まるエラーメッセージをURLとして返すように機能します。そのようなリンクを一目でわかるようにするには、CSSに以下を追加します。
a[href^="#error:"] {
background: red;
color: white;
}
開発環境で警告が生成されないようにしたい場合は、設定で直接サイレントモードを設定できます。
application:
silentLinks: true
LinkGenerator
Presenterが存在しない場合に、link()
メソッドと同様の快適さでリンクを作成するにはどうすればよいでしょうか?そのためにNette\Application\LinkGeneratorがあります。
LinkGeneratorは、コンストラクタ経由で渡してもらい、その後その link()
メソッドを使用してリンクを作成できるサービスです。
Presenterとの違いがあります。LinkGeneratorはすべてのリンクを直接絶対URLとして作成します。さらに、「現在のPresenter」は存在しないため、ターゲットとしてアクション名
link('default')
だけを指定したり、モジュールへの相対パスを指定したりすることはできません。
不正なリンクは常に Nette\Application\UI\InvalidLinkException
をスローします。