EC-CUBE Advent Calendar 2020 10日目の記事です。
EC-CUBE4の商品詳細ページURLをスラッグ化する方法です。
商品詳細ページのURLのスラッグ化とは以下のURLを
http://localhost:8080/products/detail/1
以下ような形に変更することです。
http://localhost:8080/products/detail/gelato
商品詳細ページURLのスラッグ化で困っていたこと
商品詳細ページのURLのスラッグ化で困っていたことが2点ありました。
1点目はProductControllerの修正
一見するとProductエンティティにslugプロパティを追加し、
Customize領域にProductControllerを作成してProductControllerの@Routeアノテーションの「requirements={“id” = “\d+”}」を削除するだけで良さそうに思いますが、
この修正だけだとParamConverterアノテーションに「findWithSortedClassCategories」メソッドが設定されていることが原因で商品ID以外の値を渡すと商品が見つかりませんというエラーが発生します。
本体のProductRepositoryのfindWithSortedClassCategoriesメソッドを修正すればエラー回避することは可能なのですが、本体を直接カスタマイズするのは避けたかったのでどうすればよいのか困っていました。
2点目はテンプレートの商品詳細URLの書き換え
テンプレートの商品詳細URL。以下のようにパラメーターで商品IDを渡しているのでこれをスラッグを渡すようにする必要があります。
{{ url('product_detail', {'id': Product.id}) }}
この2点を回避した商品詳細ページURLのスラッグ化する方法は以下の通りとなります。
Productエンティティにslugプロパティを追加
ProductTraitを作成して、Productエンティティにslugプロパティを追加してください。
商品編集ページにスラッグ項目を表示させるため、@FormAppendアノテーションを追加しています。
また、slugはユニークにする必要があるので、loadValidatorMetadataメソッドでユニークチェックしています。
あと、slugのバリデーションは行っていないので文字数制限など適当に設定してください。
ProductControllerをカスタマイズ
Customize領域にProductControllerを作って、EC-CUBE本体の商品情報ページを修正します。
修正している点は@Routeアノテーションと@ParamConverterアノテーション。
@ParamConverterはデフォルトではDoctrineParamConverterが使われるのですが、DoctrineParamConverterを使うとスラッグ化するときにエラーが発生するので、後で独自のParamConverterを実装します。
独自のParamConverterを実装
「ProductConverter」という名前のParamConverterを実装します。
@ParamConverterの属性名(name)に「product_detail」を指定し、属性クラス(class)にProductエンティティ、オプションのidにURLの変数名を指定した場合、ProductConverterは実行されます。
ProductConverterの設定方法は、上記コントローラーの@ParamConverterを確認してください。
テンプレートの商品詳細URLの自動書き換え
テンプレートの商品詳細URLを一つ一つ書き換えていくのは大変なので、TwigExtensionを使って自動で書き換えます。
以下のようにTwigExtensionを用意すると、スラッグが登録されている商品はスラッグのURL、スラッグが登録されていない商品は商品IDのURLが自動で生成されます。
以上で完成です。
商品編集ページでスラッグを登録して、スラッグで商品ページにアクセスしてみてください。