2016-03-10 30 views
3

我有一個幫助函數可以生成有用的HTML標記。我的功能通常用一些參數來調用,包括一些用I18n my_helper(t(:translation_symbol))翻譯的文本。攔截和處理幫手中缺少的翻譯

我用那個的I18n t翻譯幫手,它(如果保持不變)的文本輸出一些<span class="translation missing">...</span>不用翻譯

我想知道如何以最佳方式「攔截」這個翻譯錯過了那麼

  • 我可以在我的助手正確地呈現他們我的助手外
  • 正常行爲

在我的意見,我應該能夠同時調用

<%= my_helper(t(:my_text)) %> # My helper needs to handle missing translations 
<%= t(:my_text) %> # I want default I18n markup (or a custom one) '<span class="translation missing">fr.my_text</span> 

我的助手

def my_helper(text=nil) 
    # Suppose my_text doesn't have a translation, text will have value 
    # => '<span class="translation-missing">fr.my_text</span>' 
    if translation_missing?(text) 
    # Code to handle missing translation 
    doSomething(remove_translation_missing_markup(text)) 
    notify_translation_missing 
    else 
    doSomething(text) 
    end 
end 

def translation_missing?(text) 
    # Uses some regex pattern to detect '<span class="translation-missing">' 
end 
def remove_translation_missing_markup(text) 
    # Uses some regex pattern to extract my_text from '<span class="translation-missing">fr.my_text</span>' 
end 

有沒有更好的解決這個辦法嗎?我對使用髒正則表達式解決方案感到不滿。

編輯:額外的要求

  • 的看法沒有額外的標記:我不想看着我的文件單獨添加raise: truedefault: xxx每一個翻譯。如果需要改變任何地方的行爲,我可以重寫t方法。
  • 在我的幫手中,如果找到翻譯,我需要一種方便的方式來操作翻譯的文本,但對於缺失的翻譯,我需要輕鬆地提取翻譯的完整路徑(fr.namespace.translation_symbol),而原始翻譯符號(translation_symbol),所以我可以在自定義標記中添加自己translation_missing

EDIT2:我喜歡那個

  • 覆蓋t幫手思考的東西rescue I18n::MissingTranslationData => e
  • 如果引發異常,創建並返回
    • 如果呈現的自定義對象一個html.erb,會輸出通常的<span class="translation..."
    • 有用字段(翻譯路徑,translation_str荷蘭國際集團),我可以在我的助手
+0

你最終找到了一個解決方案,讓你得到你想要的東西嗎? –

+0

@PaulFioravanti其實我對某些我認爲會相當酷的東西,但我不能在我的意見中得到最終的文本呈現爲HTML。看到[這個問題](http://stackoverflow.com/questions/36072697/custom-object-that-c​​onverts-to-html-in-view) –

+0

好的,很酷。希望你最終得到你想要的工作。不過,我認爲我沒有在運行時處理丟失翻譯的想法,但我認爲如果它們對於您的應用程序來說足夠大,那麼您需要確保在您之前沒有丟失翻譯進行應用程序部署,這是[i18n-tasks](https://github.com/glebm/i18n-tasks)可以提供的幫助。 –

回答

0

重用爲什麼不如下默認選項設置爲翻譯方法:

<%= t(:my_text, default: "not here") %> 

大約爲I18n.translate方法設置默認值的詳細信息,請參閱http://guides.rubyonrails.org/i18n.html#defaults

+0

編寫'default'值就像已經寫過翻譯一樣。我不想那樣。這個默認對我來說很沒用。我如何檢測翻譯實際上是在我的幫手裏面失蹤? –

2

我想你可以利用這個事實,即I18n可以配置爲當翻譯缺失時引發異常。您可以將ActionView::Base.raise_on_missing_translations = true設置爲在缺失翻譯時全局提出例外,或者您可以將:raise => true選項傳遞給t翻譯助手。

更新:既然你已經使用在你的意見t助手,你不想改變他們,我想你是重寫t幫助你ApplicationHelper唯一的選擇:

# ApplicationHelper 

def t(key, options = {}) 
    # try to translate as usual 
    I18n.t(key, options.merge(raise: true) 
rescue I18n::MissingTranslationData => e 
    # do whatever you want on translation missing, e.g. send notification to someone 
    # ... 
    "Oh-oh!" 
end 

這助手要麼返回翻譯的文本,要麼在翻譯缺失的情況下「哦,哦」。它應該按照您目前的觀點運行。

+0

這會在我的助手之外生成異常。但在我的助手之外,我不想要這個例外,也就是說我的網站會崩潰。如果可能的話,我想避免在我的觀點中使用額外的標記(我很抱歉,但我無法承受所有的觀點,逐個添加「raise:true」情況)。 –

+0

查看我的更新回答。 – BoraMa

+0

我明白了。但基本上我仍然需要添加一些標記,稍後我可以檢測到...我在想,也許在調用'my_helper(t(:my_text))''時,'t(:my_text)'可以輸出某種中間對象,這個對象可以被我的幫助者輕鬆解釋,但是如果在外部調用的話塊),'to_s'(或者任何被調用的方法)會產生默認的'

1

由於缺少翻譯似乎是在你的應用程序一個痛點,而不是讓你的應用程序代碼不斷地在尋找是否存在翻譯或沒有,如果可能的話我會主張確保您總是有翻譯潛在呼叫t,無論區域設置(這是所有假設您撥打my_helper(t(:translation_symbol)):translation_symbol鍵都是靜態的,保存在您的config/locales目錄中,並且不會動態生成)。

可以使用這樣做的I18n-tasks gem到:

  • 確保您的應用程序沒有丟失未使用的密鑰,所以你應該能夠刪除丟失的翻譯處理您的輔助方法
  • 零件
  • 如果有任何缺失或未使用的翻譯,使您的測試套件/構建過程失敗,因此沒有其他人觸及代碼庫意外偷偷地通過。見instructions on copying over their RSpec test