سؤال

كيف يمكنني القيام بجعل طريقي يتعرف على معلمة بادئة اختيارية على النحو التالي:

/*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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top