إنشاء طرق مع بادئة مسار اختيارية
-
03-07-2019 - |
سؤال
كيف يمكنني القيام بجعل طريقي يتعرف على معلمة بادئة اختيارية على النحو التالي:
/*lang/controller/id
في أن جزء lang اختياري ، وله قيمة افتراضية إذا لم يتم تحديده في عنوان URL:
/en/posts/1 => lang = en
/fr/posts/1 => lang = fr
/posts/1 => lang = en
تعديل
من الناحية المثالية ، أتطلع إلى القيام بذلك عبر العديد من وحدات التحكم والإجراءات عن طريق تعيين مساحة الاسم:
map.namespace "*lang" do |lang|
lang.resources :posts
lang.resources :stories
end
المحلول
حسنًا ، لقد تمكنت من فرز هذه المشكلة:
لا توجد طريقة للقيام بذلك في القضبان افتراضيًا (على الأقل ، ليس بعد). بدلاً من استخدام مساحات الأسماء والقيم الافتراضية ، كنت بحاجة إلى التثبيت مرشح توجيه Sven Fuchs.
بمجرد تثبيت البرنامج المساعد ، أضفت الملف التالي إلى دليل LIB الخاص بي:
require 'routing_filter/base'
module RoutingFilter
class Locale < Base
# remove the locale from the beginning of the path, pass the path
# to the given block and set it to the resulting params hash
def around_recognize(path, env, &block)
locale = nil
path.sub! %r(^/([a-zA-Z]{2})(?=/|$)) do locale = $1; '' end
returning yield do |params|
params[:locale] = locale || 'en'
end
end
def around_generate(*args, &block)
locale = args.extract_options!.delete(:locale) || 'en'
returning yield do |result|
if locale != 'en'
result.sub!(%r(^(http.?://[^/]*)?(.*))){ "#{$1}/#{locale}#{$2}" }
end
end
end
end
end
أضفت هذا الخط إلى Routes.rb:
map.filter 'locale'
هذا يملأ أساسا قبل وبعد الخطاف ، الذي تم إنشاؤه بواسطة المكون الإضافي ، الذي يلف توجيه القضبان.
عندما يتم التعرف على عنوان URL ، وقبل أن يفعل القضبان أي شيء معه ، يتم استدعاء طريقة Around_Rectinize. سيؤدي ذلك إلى استخراج رمز من حرفين يمثل اللغة ، ويمرره في المعايير ، مما يتخلف عن "en" إذا لم يتم تحديد لغة.
وبالمثل ، عند إنشاء عنوان URL ، سيتم دفع المعلمة المحلية إلى عنوان URL على الجانب الأيسر.
هذا يعطيني عناوين URL والتعيينات التالية:
/ => :locale => 'en'
/en => :locale => 'en'
/fr => :locale => 'fr'
يعمل جميع مساعدي URL الحاليين كما كان من قبل ، مع الفرق الوحيد هو أنه ما لم يتم تحديد اللغة ، يتم الحفاظ عليها:
home_path => /
home_path(:locale => 'en') => /
home_path(:locale => 'fr') => /fr
نصائح أخرى
يمكنك تحديد الإعدادات الافتراضية في طريق باستخدام :defaults
مفتاح. جرب هذا:
map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show',
:defaults => { :lang => 'en' }
أفهم أن هذا السؤال القديم ، لكنه قد يكون مفيدًا.
map.with_options(:path_prefix => ":locale") do |m|
m.resources :posts
m.resources :stories
end
وعليك إضافة قبل التصفية إلى وحدة تحكم التطبيق لتحديد اللغة ، مثل
before_filter :define_locale
def define_locale
if params[:locale] == nil
I18n.locale = 'en'
else
I18n.locale = params[:locale]
end
end
أظن (لا وقت للاختبار الآن) أن هذا قد ينجح:
map.connect ':language/posts/:id', :controller => 'posts', :action => 'show'
map.connect 'posts/:id', :controller => 'posts', :action => 'show'
حسنًا ، جربته - إنه يعمل ، على Rails 2.1.1 على الأقل. لذلك هذا جيد. لا يمكن الحصول على فكرة: الافتراضية للعمل ، على الرغم من ذلك ، وهو عار ، لأنه مجفف.
يعتقد أنه يمكنك في وقت واحد استخدام [مفتاح] => لا شيء لتحديد معلمة اختيارية. شيء مثل:
map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil