使用Haml::Engine与Rails方法

3
我希望有一个耙子任务,可以读取HAML文件并将其创建为静态html文件。这样做的原因是我想以动态方式本地化我的错误页面,具体方法在这里描述:http://devcorner.mynewsdesk.com/2010/01/13/rails-i18n-and-404500-error-pages/ 以下是编写错误页面的方法。
def write_error_page(status, locale = nil)
  dest_filename = [status.to_s, locale, "html"].compact.join(".")
  File.open(File.join(Rails.root, "public", dest_filename), "w") do |file|
    path = File.join(Rails.root, "app", "views", "errors", "#{status}.haml")
    file.print Haml::Engine.new(File.read(path)).render
  end   
end

问题在于Haml::Engine没有可用的Rails方法。因此,当我尝试读取haml文件时,文件中每个Rails方法都会出现错误(我想使用诸如image_tag、form_for和I18n.translate之类的方法)。
我注意到这里有一个已解决的类似问题:Rails HAML engine rendering
然而,当我尝试上述链接中提到的解决方案时,我会得到以下错误:"undefined local variable or method `config' for #”。
我该如何使Rails方法在Haml::Engine中正常工作,以便我可以读取HAML文件?我还尝试过切换到ERB,但是发现它会导致相同的问题,至少有人在这里部分解决了这个问题:render erb from database into view problem please help! 但这个解决方案对我也没用。
我也愿意尝试除了使用Haml::Engine之外的其他解决方案。我研究了capture_haml帮助程序,但不知道它怎么能帮我。
3个回答

0
你需要将:environment作为你的rake任务的依赖项:
task :some_task => :environment do
  # stuff here
end

这将加载Rails。听起来它还没有被加载。


不对,那不是这样的。我从这个rake任务中调用write_error_pages方法: task :write_error_pages => :environment do ... end我在write_error_page方法中使用了rails方法,但没有在Haml::Engine内部使用,因为Haml::Engine是一种在不依赖于rails的情况下使用Haml的方式。所以从这个意义上讲,这似乎是错误的方法,但我找不到其他方法来解决这个问题。 - Kusti

0

我刚才意识到,在这种情况下,我不需要使用Haml::Engine,因为我在Rails环境中,所以可以直接调用render函数。我真是太傻了。

但是,在rake任务中调用render并不完全简单,因为我们不在控制器或视图中(因此连Rails纯粹主义者都说你永远不应该这样做,我认为,在这种情况下似乎是最简单的方法),所以我在这里发布了我使用的代码(我使用了这里提到的方法:http://wholemeal.co.nz/blog/2011/04/05/rendering-from-a-model-in-rails-3/)。

def write_error_page(status, locale = nil)
  dest_filename = [status.to_s, locale, "html"].compact.join(".")
  File.open(File.join(Rails.root, "public", dest_filename), "w") do |file|
    path = File.join("app", "views", "errors", "#{status}.haml")
    file.print ActionView::Base.new(Rails.configuration.paths.app.views.first).render(:file => path)
  end   
end

我也遇到了一些问题。例如,form_for仍然无法正常工作(我想在错误页面上有一个反馈表单),所以我只是用纯HTML创建了表单(你可以将其直接注入到.haml文件中)。但是,在.haml模板中我需要让Rails的一件事情正常工作——I18n.translate方法,这个方法非常好用。

我正在尝试使用Rails.configuration.paths.app.views.first,但是它报错了,显示undefined method `app' for #Rails::Paths::Root:0x000000032ed968... 你能帮忙吗? - tbem
解决方法是使用以下代码替代:Rails.configuration.paths["app/views"].first - tbem
现在另一个问题是,我无法访问助手方法,我该如何注入它们? - tbem
在调用ActionView::Base.new之前,只需执行以下操作:包含ActionView::Helpers::ApplicationHelper。 - tbem

0

我基于你的解决方案进行了修改,因为你的方案对我来说不起作用,可能是因为视图路径的问题,还有我需要在我的应用程序助手中包含一些函数。我认为你可以通过包含以下内容来解决form_for的问题:ActionView::Base.send :include, ActionView::Helpers::FormHelper

我将格式更改为HTML,因为这正是我所需要的...

def to_html
  ActionView::Base.send :include, ActionView::Helpers::ApplicationHelper

  File.open(File.join(Rails.root, "public", 'test.html'), "w") do |file|

  file.print ActionView::Base.new(Rails.configuration.paths["app/views"].first).render(
                :partial => 'partial_folder/partial', 
                :format => :html,
                :locals => { :model => self}
              )
  end  
end

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