在Rails 3视图中国际化Markdown文件

4

我目前正在学习Michael Hartl的Rails教程,同时尝试一些书中未涉及的其他内容。完成第5章后,我决定将视图代码更改为HAML,对页面进行国际化处理,并将静态内容放入单独的(非部分)Markdown文件中,使用RDiscount gem进行渲染。例如:

app/views/static_pages/about.html.haml

- provide(:title, t('.about_us'))
:markdown
  #{render file: "static_pages/about.#{params[:locale]}.md"}

static_pages 目录下,我有像 about.en.md, about.it.md, about.ja.md 这样的 Markdown 文件,因此在 :locale 参数中插入变量会决定哪个语言的 Markdown 文件被渲染。
我的问题是:
  1. The static_pages directory is a bit crowded with Markdown files, so are there any sensible default/best practice locations (perhaps outside of the app directory) to keep these Markdown files, where they could be presumably be edited by people who don't need to know about the inner workings of the app?
  2. What better ways are there to implement rendering multi-lingual Markdown files in views? My use of :locale and the double string-interpolation seems inelegant.
  3. Is there a way to change this code so that I can pass Ruby variables into the Markdown file? I know I can, for example, use a #{language} variable in the Markdown by just changing about.en.md into a HAML partial (_about.en.html.haml) and change the code to look something like:

    app/views/static_pages/about.html.haml

    - provide(:title, t('.about_us'))
    :markdown
      #{render "about.#{params[:locale]}", language: 'Markdown!'}
    

    But, is there a way to do this without changing the Markdown file into another type of file? If such a way exists, is it recommended/feasible?

1个回答

5
在查看了这个StackOverflow答案之后,似乎最好的i18n Markdown文件位置是它们自己的动作名称目录,在config/locales目录下,并且有很好的机会重构StaticPagesController的所有视图中的render代码。因此,使用about.html.haml作为以下示例,homehelpaboutcontact视图中的render调用已更改为完全相同的代码:
- provide(:title, t('.about_us'))
:markdown
  #{render file: localized_page_for(action_name, params[:locale])}

localized_page_for方法定义在StaticPagesHelper中:

app/helpers/static_pages_helper.rb

module StaticPagesHelper
  def localized_page_for(action, locale)
    "#{Rails.root}/config/locales/#{action}/#{action}.#{locale.to_s}.md"
  end
end

现在所有Markdown文件已从app/views/static_pages目录中取出,并使用逻辑目录(例如config/locales/about/about.en.md)和区域设置,通过ActionControlleraction_name属性进行调用,以减少混乱。

至于上述第二个问题,字符串插值似乎很常见,可解决这种问题,所以我认为它也足够"优雅"。

至于上述第三个问题,在详尽搜索后,我没有找到任何一种方法可以将变量传递到纯Markdown文件中,而且文档似乎没有关于支持它们的说明,所以我得出结论:这是不可能的。如果必须将Ruby变量传递给Markdown,则需要通过另一个解释器运行该文件,就像此StackOverflow答案中描述的那样。

更新:

在对应用程序运行安全扫描器Brakeman之后,由于动态将params[:locale]传递给render调用而不是传递静态字符串,它出现了潜在的动态渲染路径安全警告(尽管是弱警告)。因此,我将调用localized_page方法移到了视图之外,将该方法本身从StaticPagesHelper移出(因此该文件现在为空),并移到了StaticPagesController中,然后在每个方法中实例化一个@page实例变量以传递给视图。总之,现在的代码看起来像这样,不会收到安全警告:

app/controllers/static_pages_controller.rb

class StaticPagesController < ApplicationController

  before_filter :localized_page, only: [:help, :about, :contact]

  def home
    if signed_in?
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    else
      localized_page
    end
  end

 def help
 end

 def about
 end

 def contact  
 end

 private

   def localized_page
    @page = "#{Rails.root}/config/locales/"\
            "#{action_name}/#{action_name}.#{params[:locale].to_s}.md"
   end
end

app/views/static_pages/about.html.haml

- provide(:title, t('.about_us'))
:markdown
  #{render file: @page}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接