Module: Roda::RodaPlugins::SymbolMatchers
- Defined in:
- lib/roda/plugins/symbol_matchers.rb
Overview
The symbol_matchers plugin allows you do define custom regexps to use for specific symbols. For example, if you have a route such as:
r.on :username do |username|
# ...
end
By default this will match all nonempty segments. However, if your usernames must be 6-20 characters, and can only contain a-z
and 0-9
, you can do:
plugin :symbol_matchers
symbol_matcher :username, /([a-z0-9]{6,20})/
Then the route will only if the path is /foobar123
, but not if it is /foo
, /FooBar123
, or /foobar_123
.
By default, this plugin sets up the following symbol matchers:
- :d
-
/(\d+)/
, a decimal segment - :rest
-
/(.*)/
, all remaining characters, if any - :w
-
/(\w+)/
, an alphanumeric segment
If the placeholder_string_matchers plugin is loaded, this feature also applies to placeholders in strings, so the following:
r.on "users/:username" do |username|
# ...
end
Would match /users/foobar123
, but not /users/foo
, /users/FooBar123
, or /users/foobar_123
.
If using this plugin with the params_capturing plugin, this plugin should be loaded first.
You can provide a block when calling symbol_matcher
, and it will be called for all matches to allow for type conversion:
symbol_matcher(:date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
Date.new(y.to_i, m.to_i, d.to_i)
end
route do |r|
r.on :date do |date|
# date is an instance of Date
end
end
If you have a segment match the passed regexp, but decide during block processing that you do not want to treat it as a match, you can have the block return nil or false. This is useful if you want to make sure you are using valid data:
symbol_matcher(:date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
y = y.to_i
m = m.to_i
d = d.to_i
Date.new(y, m, d) if Date.valid_date?(y, m, d)
end
You can have the block return an array to yield multiple captures.
The second argument to symbol_matcher can be a symbol already registered as a symbol matcher. This can DRY up code that wants a conversion performed by an existing class matcher or to use the same regexp:
symbol_matcher :employee_id, :d do |id|
id.to_i
end
symbol_matcher :employee, :employee_id do |id|
Employee[id]
end
With the above example, the :d matcher matches only decimal strings, but yields them as string. The registered :employee_id matcher converts the decimal string to an integer. The registered :employee matcher builds on that and uses the integer to lookup the related employee. If there is no employee with that id, then the :employee matcher will not match.
If using the class_matchers plugin, you can provide a recognized class matcher as the second argument to symbol_matcher, and it will work in a similar manner:
symbol_matcher :employee, Integer do |id|
Employee[id]
end
Blocks passed to the symbol matchers plugin are evaluated in route block context.
If providing a block to the symbol_matchers plugin, the symbol may not work with the params_capturing plugin. Note that the use of symbol matchers inside strings when using the placeholder_string_matchers plugin only uses the regexp, it does not respect the conversion blocks registered with the symbols.
Defined Under Namespace
Modules: ClassMethods, RequestMethods
Class Method Summary collapse
Class Method Details
.configure(app) ⇒ Object
107 108 109 110 111 112 |
# File 'lib/roda/plugins/symbol_matchers.rb', line 107 def self.configure(app) app.opts[:symbol_matchers] ||= {} app.symbol_matcher(:d, /(\d+)/) app.symbol_matcher(:w, /(\w+)/) app.symbol_matcher(:rest, /(.*)/) end |
.load_dependencies(app) ⇒ Object
102 103 104 105 |
# File 'lib/roda/plugins/symbol_matchers.rb', line 102 def self.load_dependencies(app) app.plugin :_symbol_regexp_matchers app.plugin :_symbol_class_matchers end |