Module: R18n::Filters

Defined in:
lib/r18n-core/filters.rb

Overview

Filter is a way, to process translations: escape HTML entries, convert from Markdown syntax, etc.

In translation file filtered content must be marked by YAML type:

filtered: !!custom_type
  This content will be processed by filter

Filter function will be receive filtered content as first argument, struct with filter config as second and filter parameters as next arguments. You can set passive filter, which will process translation only on loading.

R18n::Filters.add('custom_type', :no_space) do |content, config, replace|
  content.gsub(' ', replace)
end
R18n::Filters.add('custom_type', :passive => true) do |content, config|
  content + '!'
end

i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"

Use String class as type to add global filter for all translated strings:

R18n::Filters.add(String, :escape_html) do |content, config, params|
  escape_html(content)
end

Filter config contain two parameters: translation locale and path. But it is Hash and you can add you own parameter to cross-filter communications:

R18n::Filters.add(String, :hide_truth) do |content, config|
  return content if config[:censorship_check]

  if content.scan(CENSORSHIP_WORDS[config[:locale]]).empty?
    content
  else
    "Error in #{config[:path]}"
  end
end

R18n::Filters.add('passed', :show_lie) do |content, config|
  config[:censorship_check] = true
  content
end

You can disable, enabled and delete filters:

R18n::Filters.off(:no_space))
i18n.filtered('_') #=> "This content will be processed by filter!"
R18n::Filters.on(:no_space)
i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"
R18n::Filters.delete(:no_space)

Defined Under Namespace

Classes: Filter

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.active_enabledObject

Hash of types to enabled active filters.



85
86
87
# File 'lib/r18n-core/filters.rb', line 85

def active_enabled
  @active_enabled
end

.by_typeObject

Hash of types to all Filters.



82
83
84
# File 'lib/r18n-core/filters.rb', line 82

def by_type
  @by_type
end

.definedObject

Hash of filter names to Filters.



79
80
81
# File 'lib/r18n-core/filters.rb', line 79

def defined
  @defined
end

.enabledObject

Hash of types to enabled passive and active filters.



91
92
93
# File 'lib/r18n-core/filters.rb', line 91

def enabled
  @enabled
end

.passive_enabledObject

Hash of types to enabled passive filters.



88
89
90
# File 'lib/r18n-core/filters.rb', line 88

def passive_enabled
  @passive_enabled
end

Class Method Details

.add(types, name = nil, options = {}, &block) ⇒ Object

Add new filter for type with name and return filter object. You can use String class as type to add global filter for all translated string.

Filter content will be sent to block as first argument, struct with config as second and filters parameters will be in next arguments.

Options:

  • position – change order on processing several filters for same type.

    Note that passive filters will be always run before active.
    
  • passive – if true, filter will process only on translation loading. Note that you must add all passive before load translation.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/r18n-core/filters.rb', line 150

def add(types, name = nil, options = {}, &block)
  options, name = name, nil if name.is_a? Hash
  types = Array(types)

  unless name
    @last_auto_name ||= 0
    begin
      @last_auto_name += 1
      name = @last_auto_name
    end while defined.has_key? name
  else
    delete(name)
  end

  filter = Filter.new(name, types, block, true, options[:passive])
  @defined[name] = filter

  types.each do |type|
    @by_type[type] = [] unless @by_type.has_key? type
    if options.has_key? :position
      @by_type[type].insert(options[:position], filter)
    else
      @by_type[type] << filter
    end
    rebuild_enabled! type
  end

  filter
end

.delete(filter) ⇒ Object

Delete filter by name or Filter object.



181
182
183
184
185
186
187
188
189
190
# File 'lib/r18n-core/filters.rb', line 181

def delete(filter)
  filter = @defined[filter] unless filter.is_a? Filter
  return unless filter

  @defined.delete(filter.name)
  filter.types.each do |type|
    @by_type[type].delete(filter)
    rebuild_enabled! type
  end
end

.off(filter) ⇒ Object

Disable filter by name or Filter object.



193
194
195
196
197
198
199
# File 'lib/r18n-core/filters.rb', line 193

def off(filter)
  filter = @defined[filter] unless filter.is_a? Filter
  return unless filter

  filter.enabled = false
  filter.types.each { |type| rebuild_enabled! type }
end

.on(filter) ⇒ Object

Turn on disabled filter by name or Filter object.



202
203
204
205
206
207
208
# File 'lib/r18n-core/filters.rb', line 202

def on(filter)
  filter = @defined[filter] unless filter.is_a? Filter
  return unless filter

  filter.enabled = true
  filter.types.each { |type| rebuild_enabled! type }
end

.process(enabled, type, value, locale, path, params) ⇒ Object

Process value by filters in enabled.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/r18n-core/filters.rb', line 94

def process(enabled, type, value, locale, path, params)
  config = { :locale => locale, :path => path }

  enabled[type].each do |filter|
    value = filter.call(value, config, *params)
  end

  if value.is_a? String
    value = TranslatedString.new(value, locale, path)
    process_string(enabled, value, config, params)
  else
    value
  end
end

.process_string(enabled, value, config, params) ⇒ Object

Process value by global filters in enabled.



110
111
112
113
114
115
116
117
118
# File 'lib/r18n-core/filters.rb', line 110

def process_string(enabled, value, config, params)
  if config.is_a? String
    config = { :locale => value.locale, :path => config }
  end
  enabled[String].each do |f|
    value = f.call(value, config, *params)
  end
  value
end

.rebuild_enabled!(type) ⇒ Object

Rebuild active_enabled and passive_enabled for type.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/r18n-core/filters.rb', line 121

def rebuild_enabled!(type)
  @passive_enabled[type] = []
  @active_enabled[type] = []
  @enabled[type] = []

  @by_type[type].each do |filter|
    if filter.enabled?
      @enabled[type] << filter
      if filter.passive?
        @passive_enabled[type] << filter
      else
        @active_enabled[type] << filter
      end
    end
  end
end