Gettext 和 Haml on Rails / rake updatepo 出现非常奇怪的问题

发布于 2024-07-30 09:06:37 字数 2434 浏览 6 评论 0原文

我使用 Rails 2.3.3,并使用 Haml 2.0.9 作为模板,使用 Gettext-Rails 2.0.4 进行翻译。 Haml 的工作方式就像一个魅力,gettext 也像它应该的那样工作。

但使用“rake updatepo”时我无法让 Gettext 解析 Haml 文件。 我创建了一个如下所示的自定义解析器:

# lib/haml_parser.rb
require 'gettext_rails/tools'
require 'haml'
# Haml gettext parser
module HamlParser
  module_function

  def target?(file)
    File.extname(file) == ".haml"
  end

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end
end

GetText::RGetText.add_parser(HamlParser)

我的 Rakefile 如下所示:

# Rakefile
require(File.join(File.dirname(__FILE__), 'config', 'boot'))

require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

require 'tasks/rails'

desc "Create mo-files for L10n"
task :makemo do
  require 'gettext_rails/tools'
  GetText.create_mofiles(true)  #(true, "po", "locale")
end

desc "Update pot/po files to match new version."
task :updatepo do
  require 'gettext_rails/tools'
  require 'haml_parser'
  MY_APP_TEXT_DOMAIN = "APP" 
  MY_APP_VERSION     = "APP 1.1.0"
  GetText.update_pofiles(MY_APP_TEXT_DOMAIN, Dir.glob("{app,lib}/**/*.{rb,rhtml,html.erb,haml,html.haml,rjs}"),
                         MY_APP_VERSION)
end

这遵循解析 Haml 文件的已知方法( http://www.paulgillard.me.uk/2008/3/8/rails-haml-and-gettext )。

问题:我的 Haml 文件无法识别 MessageId。 我检查了 Haml-Parser 中的“puts”是否尝试了正确的文件,是否可以解析它们等等。 一切似乎都很好,它只是识别任何东西,并且总是只返回已经找到的 msgids,对于 Haml 文件,返回一个空数组。

奇怪的是:当我在控制台中输入此内容时,一切正常:

$$ script/console
Loading development environment (Rails 2.3.3)
>> require 'gettext_rails/tools'
=> []
>> require 'haml'
=> []
>> file = "app/views/sessions/new.haml"
=> "app/views/sessions/new.haml"
>> haml = Haml::Engine.new(IO.readlines(file).join)
=> #<Haml::Engine:0x4254104 @tab_change=0, @block_opened=false, @inden [...]
>> code = haml.precompiled.split(/$/)
=> [" content_for :head do;", "\nhaml_temp =  stylesheet_link [...]
>> GetText::RubyParser.parse_lines(file, code, [])
=> [["Login", "app/views/sessions/new.haml:4"], [...]

正如您所看到的,这里一切正常(我省略了长回报)。 我有点奇怪为什么我的 Rake 任务不是这种情况。

有人有主意吗? 你真的会让我成为一个快乐的书呆子!

谢谢!

I'm on Rails 2.3.3 and using Haml 2.0.9 for my templates and Gettext-Rails 2.0.4 for the translation. Haml works like a charm and gettext is also working like it should.

But I cant get Gettext to parse Haml Files when using "rake updatepo". I created a custom parser like this:

# lib/haml_parser.rb
require 'gettext_rails/tools'
require 'haml'
# Haml gettext parser
module HamlParser
  module_function

  def target?(file)
    File.extname(file) == ".haml"
  end

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end
end

GetText::RGetText.add_parser(HamlParser)

My Rakefile looks like this:

# Rakefile
require(File.join(File.dirname(__FILE__), 'config', 'boot'))

require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

require 'tasks/rails'

desc "Create mo-files for L10n"
task :makemo do
  require 'gettext_rails/tools'
  GetText.create_mofiles(true)  #(true, "po", "locale")
end

desc "Update pot/po files to match new version."
task :updatepo do
  require 'gettext_rails/tools'
  require 'haml_parser'
  MY_APP_TEXT_DOMAIN = "APP" 
  MY_APP_VERSION     = "APP 1.1.0"
  GetText.update_pofiles(MY_APP_TEXT_DOMAIN, Dir.glob("{app,lib}/**/*.{rb,rhtml,html.erb,haml,html.haml,rjs}"),
                         MY_APP_VERSION)
end

This follows the known approach for parsing Haml files ( http://www.paulgillard.me.uk/2008/3/8/rails-haml-and-gettext ).

The problem: No MessageIds are recognized from my Haml files. I checked with "puts" in the Haml-Parser if it tried the right files, could parse them and so on. Everything seemed to be fine, it just recognize anything and always returned only the already found msgids and for the Haml file an empty Array.

The strange thing: When I enter this in my console, everything works:

$ script/console
Loading development environment (Rails 2.3.3)
>> require 'gettext_rails/tools'
=> []
>> require 'haml'
=> []
>> file = "app/views/sessions/new.haml"
=> "app/views/sessions/new.haml"
>> haml = Haml::Engine.new(IO.readlines(file).join)
=> #<Haml::Engine:0x4254104 @tab_change=0, @block_opened=false, @inden [...]
>> code = haml.precompiled.split(/$/)
=> [" content_for :head do;", "\nhaml_temp =  stylesheet_link [...]
>> GetText::RubyParser.parse_lines(file, code, [])
=> [["Login", "app/views/sessions/new.haml:4"], [...]

As you can see everything works here (I left out the long returns). I'm kind of freaking out why this isn't the case in my Rake Task.

Anyone has an idea? You would really make me a happy Nerd!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

红颜悴 2024-08-06 09:06:37

刚刚遇到了同样的问题,经过一番调试后我找到了原因:Haml 中的大部分输出是由 "" 字符串中的 #{} 内部的指令生成的,该构造似乎欺骗了 RubyParser 类。 如果“普通”Ruby 文件中有类似 "#{_('some text')}" 的内容,那么它也不会被识别。

我的解决方案是稍微打乱 Haml 预编译的代码,并在 "#{}" 之外获取 _() 调用。 这就是第 4 行中的正则表达式所做的事情。

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled
    code = code.gsub(/(.*#\{(_hamlout.adjust_tabs\(\d+\);\s*)?haml_temp)\s*=\s*(_\(['"].+['"]\))/) { |m| "haml_temp = #{$3}; #{$1}" }
    code = code.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end

这修复了我的项目中大约 80% 的情况,这对我来说已经足够好了。 剩下的 20% 有时可以通过将以下内容更改为:

%tag= _('text')

来修复:

%tag
  = _('text')

如果这没有帮助,您可以使用以下技巧:

- txt = _('text')
= txt

不过,还没有尝试 ruby​​_gettext_extractor gem。

Just had the same problem and after a bit of debugging I found the cause: most of the output in Haml is generated by instructions inside of #{} in "" strings and that construct seems to fool the RubyParser class. If you had something like "#{_('some text')}" in a "normal" Ruby file, this would not be recognized, too.

My solution was to shuffle the Haml-precompiled code a little bit and get the _() calls outside of "#{}". That what the regexp does in line 4.

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled
    code = code.gsub(/(.*#\{(_hamlout.adjust_tabs\(\d+\);\s*)?haml_temp)\s*=\s*(_\(['"].+['"]\))/) { |m| "haml_temp = #{$3}; #{$1}" }
    code = code.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end

This fixes about 80% of cases in my project, which was good enough for me. The remaining 20% sometimes can be fixed by changing:

%tag= _('text')

into:

%tag
  = _('text')

And if that does not help, you can use following trick:

- txt = _('text')
= txt

Didn't try the ruby_gettext_extractor gem yet, though.

醉酒的小男人 2024-08-06 09:06:37

ruby_gettext_extractor 可能有助于修复 gettext 字符串提取。 特别是当您使用 HAML 2.2 时,它更改了其内部格式并完全破坏了 gettext 提取过程。

ruby_gettext_extractor might help fix the gettext string extraction. Especially when you're using HAML 2.2 which changed it's internal format and completely broke the gettext extraction process.

情深缘浅 2024-08-06 09:06:37

尝试修改 haml_parser.rb 以查看解析器卡在哪里。

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    puts "Parsing Haml File: #{file}"
    RubyParser.parse_lines(file, code, ary)
  end

我在升级设置时遇到了自己的问题。

Rails 2.3.4
gettext 2.0.4
haml 2.2.8

据我所知,这主要是由于 HAML 2.2 中的变化
使其输出无法被 gettext 默认解析的引擎
RubyParser。

我已经尝试过宝石
retoo-ruby_gettext_extractor (0.2.1)
这取决于
红宝石解析器
没有成功。

这个 ruby​​_parser 有一个它自己的 RubyParser 类,并且与
Gettext 的 RubyParser 模块。 这是一个经典案例来说明为什么我们应该
命名空间我们的代码。 -_-

通过更改 RubyParser 的名称来破解它后
gems,我可以使用 retoo 来解析模板文件
gettext_extractor/rubyparser gems。 但是,解析器无法正常工作
我的非拉丁模板文件。 我的 HamlParser 类如下。 任何人都行
尝试解决这个问题吗? 一百万谢谢!

# haml_parser.rb
require 'rubygems'
require 'haml'
require 'gettext_rails/tools'
require 'ruby_gettext_extractor'

module HamlParser
  module_function

  def target?(file)
    File.extname(file) == '.haml'
  end

  def parse(file, ary = [])
    bypass = ! File.basename(file, 
'.haml').match(/(vi|zh|zh_HK|id|th)$/).nil?
    puts "HamlParser:#{file}:bypass:#{bypass}"
    return ary if bypass

    haml = Haml::Engine.new(IO.readlines(file).join)
    result = nil
    begin
      #result = GetText::RubyParser.parse_lines(file, 
haml.precompiled.split(/$/), ary)
      result = RubyGettextExtractor.parse_string(haml.precompiled, file, 
ary)
    rescue Exception => e
      puts "Error:#{file}"
      raise e
    end
    result
  end
end

GetText::RGetText.add_parser(HamlParser)

Try modifying your haml_parser.rb to see where the parser gets stuck.

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    puts "Parsing Haml File: #{file}"
    RubyParser.parse_lines(file, code, ary)
  end

I'm having problems of my own in upgrading my setup.

Rails 2.3.4
gettext 2.0.4
haml 2.2.8

From what I have gathered it is largely due to the change of in HAML 2.2
Engine that made it's output unparseable by the gettext's default
RubyParser.

I have tried the gems
retoo-ruby_gettext_extractor (0.2.1)
that depends on
ruby_parser
without success.

This ruby_parser has a RubyParser class of it's own and conflicts with
Gettext's RubyParser module. So here's a classical case of why we should
namespace our code. -_-

After hacking it to work by changing the names of the RubyParser in the
gems, I can make it work to parse en template files, using retoo's
gettext_extractor/rubyparser gems. However, the parser doesn't work on
my non-latin template files. My HamlParser class as below. Anyone can
have a go and fix this? A million thanks!

# haml_parser.rb
require 'rubygems'
require 'haml'
require 'gettext_rails/tools'
require 'ruby_gettext_extractor'

module HamlParser
  module_function

  def target?(file)
    File.extname(file) == '.haml'
  end

  def parse(file, ary = [])
    bypass = ! File.basename(file, 
'.haml').match(/(vi|zh|zh_HK|id|th)$/).nil?
    puts "HamlParser:#{file}:bypass:#{bypass}"
    return ary if bypass

    haml = Haml::Engine.new(IO.readlines(file).join)
    result = nil
    begin
      #result = GetText::RubyParser.parse_lines(file, 
haml.precompiled.split(/$/), ary)
      result = RubyGettextExtractor.parse_string(haml.precompiled, file, 
ary)
    rescue Exception => e
      puts "Error:#{file}"
      raise e
    end
    result
  end
end

GetText::RGetText.add_parser(HamlParser)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文