إضافة بادئة إلى كل عنوان URL في CakePhP
سؤال
ما هي أنظف طريقة لإضافة بادئة إلى كل عنوان URL في CakePhP ، مثل معلمة اللغة؟
http://example.com/en/controller/action
http://example.com/ru/admin/controller/action
يحتاج إلى العمل مع البادئات "الحقيقية" مثل admin
, ، ومن الناحية المثالية عنوان URL العاري /controller/action
يمكن إعادة توجيهها إلى /DEFAULT-LANGUAGE/controller/action
.
إنه يعمل في تطبيق مجهز رجوعًا بالنسبة لي الآن ، لكنه كان نوعًا من الاختراق ، وأحتاج إلى تضمين معلمة اللغة باليد في معظم الروابط ، وهذا ليس جيدًا.
لذا فإن السؤال ذو شقين:
- ما هي أفضل طريقة لهيكلة المسارات ، وبالتالي يتم تضمين معلمة اللغة ضمنيًا بشكل افتراضي دون الحاجة إلى تحديد كل مسار محدد حديثًا؟
Router::connect('/:controller/:action/*', ...)
يجب أن تشمل ضمنيا البادئة.- يجب أن تكون المعلمة متاحة في
$this->params['lang']
أو في مكان مشابه لتقييمه فيAppController::beforeFilter()
.
- كيف تحصل على
Router::url()
لتضمين البادئة تلقائيًا في عنوان URL ، إن لم يكن محددًا بشكل صريح؟Router::url(array('controller' => 'foo', 'action' => 'bar'))
يجب أن تعود/en/foo/bar
- حيث
Controller::redirect()
,Form::create()
او حتىRouter::url()
تحتاج مباشرة إلى الحصول على نفس السلوك ، والتجاوز كل وظيفة واحدة ليس خيارًا حقًا.Html::image()
على سبيل المثال ، يجب أن تنتج عنوان URL بدون بادئة.
يبدو أن الأساليب التالية تتصل بها Router::url
.
Controller::redirect
Controller::flash
Dispatcher::__extractParams
عبرObject::requestAction
Helper::url
JsHelper::load_
JsHelper::redirect_
View::uuid
, ، ولكن فقط لجيل التجزئة
من بين هؤلاء يبدو أن طرق وحدة التحكم والمساعد تحتاج إلى تجاوزها ، يمكنني العيش بدون JsHelper
. ستكون فكرتي هي كتابة وظيفة عامة في AppController
أو ربما فقط في bootstrap.php
للتعامل مع المعلمة إدراج. ستستخدم وحدة التحكم والمساعد المتطابق هذه الوظيفة ، كما أود أن أرغب في الاتصال يدويًا Router::url
. هل سيكون هذا كافيًا؟
المحلول
اقترح Rchavik من IRC هذا الرابط: تبديل اللغة القائمة على عنوان URL CakePhP للتدويل وتوطين I18N و L10N
بشكل عام ، يبدو أن التجاوز Helper::url
قد يكون الحل.
نصائح أخرى
هذا هو في الأساس كل الشفرة التي قمت بتطبيقها لحل هذه المشكلة في النهاية (على الأقل أعتقد أن هذا كل شيء ؛-)):
/config/bootstrap.php
define('DEFAULT_LANGUAGE', 'jpn');
if (!function_exists('router_url_language')) {
function router_url_language($url) {
if ($lang = Configure::read('Config.language')) {
if (is_array($url)) {
if (!isset($url['language'])) {
$url['language'] = $lang;
}
if ($url['language'] == DEFAULT_LANGUAGE) {
unset($url['language']);
}
} else if ($url == '/' && $lang !== DEFAULT_LANGUAGE) {
$url.= $lang;
}
}
return $url;
}
}
/config/core.php
Configure::write('Config.language', 'jpn');
/app_helper.php
class AppHelper extends Helper {
public function url($url = null, $full = false) {
return parent::url(router_url_language($url), $full);
}
}
/app_controller.php
class AppController extends Controller {
public function beforeFilter() {
if (isset($this->params['language'])) {
Configure::write('Config.language', $this->params['language']);
}
}
public function redirect($url, $status = null, $exit = true) {
parent::redirect(router_url_language($url), $status, $exit);
}
public function flash($message, $url, $pause = 1) {
parent::flash($message, router_url_language($url), $pause);
}
}
/config/routes.php
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/:language/', array('controller' => 'pages', 'action' => 'display', 'home'), array('language' => '[a-z]{3}'));
Router::connect('/:language/pages/*', array('controller' => 'pages', 'action' => 'display'), array('language' => '[a-z]{3}'));
Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}'));
هذا يسمح عناوين URL الافتراضية مثل /controller/action
لاستخدام اللغة الافتراضية (JPN في حالتي) ، وعنوان URL مثل /eng/controller/action
لاستخدام لغة بديلة. يمكن تغيير هذا المنطق بسهولة في router_url_language()
وظيفة.
لكي يعمل هذا ، أحتاج أيضًا إلى تحديد طريقين لكل مسار ، واحد يحتوي على /:language/
المعلمة وواحد بدون. على الأقل لم أستطع معرفة كيفية القيام بذلك بطريقة أخرى.
قد تكون هناك طريقة أسهل لتخزين اللغة المختارة في ملف تعريف الارتباط ومن ثم لا تضطر إلى إعادة كتابة جميع عناوين URL. يمكنك أيضًا اكتشاف لغة متصفح المستخدم تلقائيًا.
لكن, ، من غير المرجح أن تستلم محركات البحث اللغات المختلفة وستفقد اللغة أيضًا إذا حاول شخص ما مشاركة الرابط.
لكن أحب الحل الكامل الذي نشرته ، شاملًا جدًا ، شكرًا. :-)