복붙노트

[RUBY-ON-RAILS] 링크 내부와 번역 텍스트 - 국제화 레일

RUBY-ON-RAILS

링크 내부와 번역 텍스트 - 국제화 레일

나는 모습이 좋아하는 텍스트를 국제화하고 싶습니다 :

텍스트에 링크가 있습니다. 이 예에 그것은 구글 가리키는 - 실제로는 내 응용 프로그램의 log_in_path를 가리 킵니다.

나는이 일을 두 가지 방법을 발견했지만, 그들 중 누구도 "권리"를 보지 않는다.

내가 아는 첫 번째 방법이 내 en.yml을 가진 포함한다 :

log_in_message: "Already signed up? <a href='{{url}}'>Log in!</a>"

그리고 내보기 :

<p> <%= t('log_in_message', :url => login_path) %> </p>

이 작품은,하지만 en.yml에 부분이있는 것은 나에게 매우 깨끗 보이지 않는다.

login.en.html.erb, 그리고 login.es.html.erb - 다른 옵션 I의 노하우가 현지화 된 뷰를 사용하고 있습니다.

유일한 다른 라인은 상기 한 것 때문에도 잘 느끼지 않는다; 뷰 (~ 30 행)의 나머지 모든보기에 대해 반복 될 것이다. 그것은 매우 건조하지 않을 것입니다.

나는 "지역화 된 부분 지문"을 사용할 수 있습니다 생각하지만 너무 cumberstone 것 같다; 나는 많은 작은 파일보기를 데 첫 번째 옵션을 선호 생각합니다.

그래서 제 질문은이를 구현하기위한 "적절한"방법은 무엇입니까?

해결법

  1. ==============================

    1.en.yml

    en.yml

    log_in_message_html: "This is a text, with a %{href} inside."
    log_in_href: "link"
    

    login.html.erb

    <p> <%= t("log_in_message_html", href: link_to(t("log_in_href"), login_path)) %> </p>
    
  2. ==============================

    2.잠시 동안 locale.yml 파일 작품이 아니라 긴 텍스트와 텍스트와 링크를 분리하는 번역 링크 (Simones 대답으로) 별도의 번역 항목에서와 같이 유지하기 어렵다. 당신이 링크와 함께 많은 문자열 / 번역을 가지고 시작하면 좀 더를 건조 할 수 있습니다.

    잠시 동안 locale.yml 파일 작품이 아니라 긴 텍스트와 텍스트와 링크를 분리하는 번역 링크 (Simones 대답으로) 별도의 번역 항목에서와 같이 유지하기 어렵다. 당신이 링크와 함께 많은 문자열 / 번역을 가지고 시작하면 좀 더를 건조 할 수 있습니다.

    내 application_helper.rb 한 도우미를했다 :

    # Converts
    # "string with __link__ in the middle." to
    # "string with #{link_to('link', link_url, link_options)} in the middle."
    def string_with_link(str, link_url, link_options = {})
      match = str.match(/__([^_]{2,30})__/)
      if !match.blank?
        raw($` + link_to($1, link_url, link_options) + $')
      else
        raise "string_with_link: No place for __link__ given in #{str}" if Rails.env.test?
        nil
      end
    end
    

    내 en.yml에서 :

    log_in_message: "Already signed up? __Log in!__"
    

    그리고 내 뷰 :

    <p><%= string_with_link(t('.log_in_message'), login_path) %></p>
    

    이 방법은 또한 링크 텍스트가 명확하게 locale.yml-파일에 정의되어있는 메시지를 번역하는 것이 더 쉽습니다.

  3. ==============================

    3.나는 홀리스 솔루션을 가져다 보석이의 그것을 밖으로이라고했다. 예제를 살펴 보자 :

    나는 홀리스 솔루션을 가져다 보석이의 그것을 밖으로이라고했다. 예제를 살펴 보자 :

    log_in_message: "Already signed up? %{login:Log in!}"
    

    그리고

    <p><%=t_link "log_in_message", :login => login_path %></p>
    

    자세한 내용은 https://github.com/iGEL/it를 참조하십시오.

  4. ==============================

    4.en.yml에서

    en.yml에서

    registration:
        terms:
          text: "I do agree with the terms and conditions: %{gtc} / %{stc}"
          gtc: "GTC"
          stc: "STC"
    

    de.yml에서

    registration:
        terms:
          text: "Ich stimme den Geschäfts- und Nutzungsbedingungen zu: %{gtc} / %{stc}"
          gtc: "AGB"
          stc: "ANB"
    

    new.html.erb에서 [추정]

    <%= t(
       'registration.terms.text',
        gtc:  link_to(t('registration.terms.gtc'),  terms_and_conditions_home_index_url + "?tab=gtc"),
        stc: link_to(t('registration.terms.stc'), terms_and_conditions_home_index_url + "?tab=stc")
     ).html_safe %>
    
  5. ==============================

    5.이 방법을 공유, holli, 대단히 감사합니다. 그것은 나를 위해 마법처럼 작동합니다. 내가 할 수있는 경우에 당신을 투표를하지만, 이것이 내가 퍼즐에 추가 조각으로 ... 적절한 명성을 결여하고있어, 그래서 내 첫 번째 게시물입니다 것입니다 : 당신의 접근 방식으로 실현 문제의 I 것은 그 내부에서 여전히하지 않습니다 일 컨트롤러. 제가 조사를 좀 해봤 rubypond에 글렌의 하나 당신의 접근 방식을 결합했다.

    이 방법을 공유, holli, 대단히 감사합니다. 그것은 나를 위해 마법처럼 작동합니다. 내가 할 수있는 경우에 당신을 투표를하지만, 이것이 내가 퍼즐에 추가 조각으로 ... 적절한 명성을 결여하고있어, 그래서 내 첫 번째 게시물입니다 것입니다 : 당신의 접근 방식으로 실현 문제의 I 것은 그 내부에서 여전히하지 않습니다 일 컨트롤러. 제가 조사를 좀 해봤 rubypond에 글렌의 하나 당신의 접근 방식을 결합했다.

    여기에 내가 무엇을 최대 온 것입니다 :

    도우미보기, 예를 들어, application_helper.rb

      def render_flash_messages
        messages = flash.collect do |key, value|
          content_tag(:div, flash_message_with_link(key, value), :class => "flash #{key}") unless key.to_s =~ /_link$/i
        end
        messages.join.html_safe
      end
    
      def flash_message_with_link(key, value)
        link = flash["#{key}_link".to_sym]
        link.nil? ? value : string_with_link(value, link).html_safe
      end
    
      # Converts
      # "string with __link__ in the middle." to
      # "string with #{link_to('link', link_url, link_options)} in the middle."
      # --> see http://stackoverflow.com/questions/2543936/rails-i18n-translating-text-with-links-inside (holli)
      def string_with_link(str, link_url, link_options = {})
        match = str.match(/__([^_]{2,30})__/)
        if !match.blank?
          $` + link_to($1, link_url, link_options) + $'
        else
          raise "string_with_link: No place for __link__ given in #{str}" if Rails.env.test?
          nil
        end
      end
    

    컨트롤러에서 :

    flash.now[:alert] = t("path.to.translation")
    flash.now[:alert_link] = here_comes_the_link_path # or _url
    

    locale.yml에서 :

    path:
      to:
        translation: "string with __link__ in the middle"
    

    뷰에서 :

    <%= render_flash_messages %>
    

    이 게시물은 holli :)을 당신을 투표 나에게 명성을 얻는 희망 모든 의견을 환영합니다.

  6. ==============================

    6.우리는 다음을했다 :

    우리는 다음을했다 :

    module I18nHelpers
      def translate key, options={}, &block
        s = super key, options  # Default translation
        if block_given?
          String.new(ERB::Util.html_escape(s)).gsub(/%\|([^\|]*)\|/){
            capture($1, &block)  # Pass in what's between the markers
          }.html_safe
        else
          s
        end
      end
      alias :t :translate
    end
    

    이상 명시 적으로 :

    module I18nHelpers
    
      # Allows an I18n to include the special %|something| marker.
      # "something" will then be passed in to the given block, which
      # can generate whatever HTML is needed.
      #
      # Normal and _html keys are supported.
      #
      # Multiples are ok
      #
      #     mykey:  "Click %|here| and %|there|"
      #
      # Nesting should work too.
      #
      def translate key, options={}, &block
    
        s = super key, options  # Default translation
    
        if block_given?
    
          # Escape if not already raw HTML (html_escape won't escape if already html_safe)
          s = ERB::Util.html_escape(s)
    
          # ActiveSupport::SafeBuffer#gsub broken, so convert to String.
          # See https://github.com/rails/rails/issues/1555
          s = String.new(s)
    
          # Find the %|| pattern to substitute, then replace it with the block capture
          s = s.gsub /%\|([^\|]*)\|/ do
            capture($1, &block)  # Pass in what's between the markers
          end
    
          # Mark as html_safe going out
          s = s.html_safe
        end
    
        s
      end
      alias :t :translate
    
    
    end
    

    다음 ApplicationController.rb 단지

    class ApplicationController < ActionController::Base
      helper I18nHelpers
    

    en.yml 파일의 키와 같은 주어

    mykey: "Click %|here|!"
    

    로 ERB에서 사용할 수 있습니다

    <%= t '.mykey' do |text| %>
      <%= link_to text, 'http://foo.com' %>
    <% end %>
    

    생성해야

    Click <a href="http://foo.com">here</a>!
    
  7. ==============================

    7.난 그냥 너무 대신 내가 문자열에 ERB 표기법을 사용하고 싶었 (예를 들어, 사용자 이름 등 로그인) YAML 파일에서 메시지를 플래시 링크를 추가하는 것보다 조금 더 많은 유연성을 원했다.

    난 그냥 너무 대신 내가 문자열에 ERB 표기법을 사용하고 싶었 (예를 들어, 사용자 이름 등 로그인) YAML 파일에서 메시지를 플래시 링크를 추가하는 것보다 조금 더 많은 유연성을 원했다.

    표시하기 전에 ERB 문자열을 디코딩하기 위해 다음과 같이 내가 도우미 코드를 수정, 그래서 나는 bootstrap_flash을 사용하고 다음과 같음 :

    require 'erb'
    
    module BootstrapFlashHelper
      ALERT_TYPES = [:error, :info, :success, :warning] unless const_defined?(:ALERT_TYPES)
    
      def bootstrap_flash
        flash_messages = []
        flash.each do |type, message|
          # Skip empty messages, e.g. for devise messages set to nothing in a locale file.
          next if message.blank?
    
          type = type.to_sym
          type = :success if type == :notice
          type = :error   if type == :alert
          next unless ALERT_TYPES.include?(type)
    
          Array(message).each do |msg|
            begin
              msg = ERB.new(msg).result(binding) if msg
            rescue Exception=>e
              puts e.message
              puts e.backtrace
            end
            text = content_tag(:div,
                               content_tag(:button, raw("&times;"), :class => "close", "data-dismiss" => "alert") +
                               msg.html_safe, :class => "alert fade in alert-#{type}")
            flash_messages << text if msg
          end
        end
        flash_messages.join("\n").html_safe
      end
    end
    

    다음 (사용 유증)와 같은 문자열을 사용하는 것이 가능하다 :

    signed_in: "Welcome back <%= current_user.first_name %>! <%= link_to \"Click here\", account_path %> for your account."
    

    이 모든 상황에 대한 작동하지 않을 수 있습니다 코드 및 문자열 정의 (특히 DRY 관점에서) 혼합하지 않아야한다는 주장이있을 수있다, 그러나 이것은 나를 위해 잘 작동하는 것 같다. 이 코드는 많은 다른 상황에 적응해야, 다음되는 중요한 비트 :

    require 'erb'
    
    ....
    
            begin
              msg = ERB.new(msg).result(binding) if msg
            rescue Exception=>e
              puts e.message
              puts e.backtrace
            end
    
  8. ==============================

    8.나는이 작업을 수행하는 간단한 방법은 단순히 수행하여 생각 :

    나는이 작업을 수행하는 간단한 방법은 단순히 수행하여 생각 :

    <%= link_to some_path do %>
    <%= t '.some_locale_key' %>
    <% end %>
    
  9. ==============================

    9.왜 첫 번째 방법을 사용할 수 있지만 분할 그것을 같은

    왜 첫 번째 방법을 사용할 수 있지만 분할 그것을 같은

    log_in_message: Already signed up?
    log_in_link_text: Log in!
    

    그리고

    <p> <%= t('log_in_message') %> <%= link_to t('log_in_link_text'), login_path %> </p>
    
  10. from https://stackoverflow.com/questions/2543936/rails-i18n-translating-text-with-links-inside by cc-by-sa and MIT license