Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

New Inflectors: Actionize and Parameterize

#713

I've attached a patch that introduces two new Inflectors: Actionize and Parameterize. Each method is tested and documented.

Actionize

Transforms a string in titleize() form to a string suitable for a action name

  "Expense Report".actionize         # => "expense_report"
  "My Totally Cool Action".actionize # => "my_totally_cool_action"
   
  @reports = ['Expense Report', 'Employee Hours']
  @reports.each do |report_name|
    link_to(report_name, "/reports/#{report_name.actionize}")
  end
  # => "<a href = '/reports/expense_report'>Expense Report</a>
        <a href = '/reports/employee_hours'>Employee Hours</a>"

Parameterize

Replaces special characters in a string so that it may be used as part of a 'pretty' URL.

==== Examples

  class Person
    def to_param
      "#{self.id}-#{self.name.parameterize}"
    end
  end

  @person = Person.find(1)
  # => #<Person id: 1, name: "Donald E. Knuth">

  <%= link_to(@person.name, person_path %>
  # => <a href="/person/1-Donald_E_Knuth">Login</a>

Reported by Matt Darby · July 27th, 2008 @ 03:39 PM

State: committed
Milestone: 2.x
Assigned to: nobody
Importance: Low

Activity

  1. James
    James

    #actionize seems useful, if only to have a more readable method for using existing functionality.

    i guess i could say the same about #parameterize, except that its function is to make a string url-safe, in a very generic way, and there are already methods (with appropriate naming, this time) which do that, right?

    http://api.rubyonrails.org/class...

    ActiveSupport::CoreExtensions::String::Inflections::underscore()

    is the same thing, I take it?

    July 27th, 2008 @ 06:03 PM

  2. Matt Darby
    Matt Darby

    #underscore and #parameterize differ in how they handle spaces and special characters.

    >> "Donald E. Knuth".underscore
    => "donald e. knuth"
    >> "Donald E. Knuth".parameterize
    => "Donald_E_Knuth"
    

    It seems that #underscore expects a camelcased string, not a more human-readable one.

    #actionize is like #tableize, but it replaces spaces with underscores (by default), and doesn't pluralize the output.

    >> "Expense Report".tableize
    => "expense reports"
    >> "Expense Report".actionize
    => "expense_report"
    

    July 27th, 2008 @ 06:46 PM

  3. James
  4. James
    James

    i guess it looks like the functionality doesn't exist, esp not under the proper naming per its usage. also, it seems genuinely useful.

    July 27th, 2008 @ 06:49 PM

  5. Clemens Kofler
    Clemens Kofler
    • Tag changed from patch to activesupport, inflector, patch

    actionize seems like a reasonable additional, although I haven't ever needed any funtionality similar to this.

    parameterize is a case by itself. There's lots of plugins out there that provide functionality to create URL friendly permalinks such as Rick's permalink_fu. If you have something like the parameterize functionality, you most definitely also have a permalink column in your model which defies the purpose of the method.

    Another thing to consider is that it doesn't play well with Rails' recent i18n efforts. In non-English speaking countries, it's likely that people's, places' etc. names include non-standard letters.

    Take Tarmo Tänav (sorry for using your name here ;-)) for example. With your Regexp, if we parameterized Tarmo, this would be something like 1-Tarmo_T_nav - which is almost certainly not what you'd want (and definitely not what Tarmo would want).

    To give you an idea what a German version of parameterize would look like, I've uploaded my current permalink creation method. Find it here. Oh, and by the way: When I wrote this code I was pretty new to Ruby and didn't know that Arrays are valid Hash keys - that's why it was inverted! ;-)

    July 28th, 2008 @ 06:46 AM

  6. Claudio Poli
    Claudio Poli

    I usually use

    t = Iconv.new("ASCII//TRANSLIT", "utf-8").iconv(text)

    t = t.downcase.strip.gsub(/[^-_\s[:alnum:]]/, '').squeeze(' ').tr(' ', '-')

    (t.blank?) ? '-' : t

    for permalinks, can be optimized though.

    July 28th, 2008 @ 09:55 AM

  7. Matt Darby
    Matt Darby

    @Clemens

    Actually, I don't use permalinks in this application. I simply override #to_param to make the link a little more helpful to the end user and for cheap SEO.

    You make a good point about #parameterize's anglo-centric-ness. I'm going to look at what kain posted and see if that will fill in the gaps.

    As for #actionize; it's really nice for DRYing up cases such as the 'report' example I listed earlier. At any rate it seems as though it would be a natural add to Inflector as the functionality doesn't exist.

    July 28th, 2008 @ 12:53 PM

  8. Damian Janowski
    Damian Janowski

    Iconv behaves differently in different platforms. Ping Xavier Noria and he'll explain.

    August 4th, 2008 @ 09:28 PM

  9. DHH
    DHH
    • State changed from new to committed

    I like parameterize and have used that in quite a few cases. I don't think the anglo approach is that big of a deal, especially not since it's usually a good idea to keep those parts of the URL ascii anyway. I've changed a few defaults, though.

    I don't really see the general use of actionize, though. That seems pretty specific to your app.

    September 10th, 2008 @ 06:29 AM

  10. Damian Janowski
    Damian Janowski

    @DHH: The point of using Iconv is not to have UTF8 URLs, but rather to "translate" special characters to their ASCII "equivalents" where possible.

    With the original patch:

    
    "Malmö".parameterize
    => "malm"
    

    With Iconv:

    
    "Malmö".parameterize
    => "malmo"
    

    I think this is very basic and should be provided out of the box. Or, at least, provide a L18N-aware extension point.

    September 10th, 2008 @ 01:24 PM

  11. Karel Minařík
    Karel Minařík

    I second Damian. Discovered this only afterwrds in Github commits feed.

    I think the "dumb" transliteration like Malmö => "malm-" really is not a practice to be encouraged by Rails. (See dropping of letters on just about any Rails-based website, be it WWR, Slideshare, etc.)

    I have commented on the commit page

    In Czech context (accented latin characters) we mainly use this solution from Adam Ciganek :

    string.chars.normalize(:kd).to_s.gsub(/[^\x00-\x7F]/, '')
    

    Although the Iconv way is much more robust.

    September 10th, 2008 @ 04:35 PM

  12. Jeff Kreeftmeijer
    Jeff Kreeftmeijer
    • Tag cleared.
    • Importance changed from to Low

    Automatic cleanup of spam.

    October 12th, 2010 @ 09:03 AM

  13. Aditya Sanghi
    Aditya Sanghi

    Automatic cleanup of spam.

    October 12th, 2010 @ 10:13 AM

  14. Jeff Kreeftmeijer