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)

You can enabled/disabled filters only for special I18n object:

R18n::I18n.new('en', nil, on_filters: [:untranslated_html, :no_space],
                          off_filters: :untranslated )

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.



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

def active_enabled
  @active_enabled
end

.by_typeObject

Hash of types to all Filters.



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

def by_type
  @by_type
end

.definedObject

Hash of filter names to Filters.



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

def defined
  @defined
end

.enabledObject

Hash of types to enabled passive and active filters.



96
97
98
# File 'lib/r18n-core/filters.rb', line 96

def enabled
  @enabled
end

.passive_enabledObject

Hash of types to enabled passive filters.



93
94
95
# File 'lib/r18n-core/filters.rb', line 93

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.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/r18n-core/filters.rb', line 127

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

  if name
    delete(name)
  else
    @last_auto_name ||= 0
    loop do
      @last_auto_name += 1
      name = @last_auto_name
      break unless defined.key? name
    end
  end

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

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

  if defined?(@new_filter_listener) && @new_filter_listener.is_a?(Proc)
    @new_filter_listener.call(filter)
  end
  filter
end

.delete(filter) ⇒ Object

Delete filter by name or Filter object.



165
166
167
168
169
170
171
172
173
174
# File 'lib/r18n-core/filters.rb', line 165

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

.listen(&_block) ⇒ Object

Return filters, which be added inside block.



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

def listen(&_block)
  filters = []
  @new_filter_listener = proc { |i| filters << i }
  yield
  @new_filter_listener = nil
  filters
end

.off(filter) ⇒ Object

Disable filter by name or Filter object.



177
178
179
180
181
182
183
# File 'lib/r18n-core/filters.rb', line 177

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.



186
187
188
189
190
191
192
# File 'lib/r18n-core/filters.rb', line 186

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

.rebuild_enabled!(type) ⇒ Object

Rebuild active_enabled and passive_enabled for type.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/r18n-core/filters.rb', line 99

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

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