https://github.com/grimen/link2
Generation next link_to-helper for Rails: Spiced with semantic beauty and intelligence.
https://github.com/grimen/link2
Last synced: 22 days ago
JSON representation
Generation next link_to-helper for Rails: Spiced with semantic beauty and intelligence.
- Host: GitHub
- URL: https://github.com/grimen/link2
- Owner: grimen
- License: mit
- Created: 2010-02-17T12:46:45.000Z (over 15 years ago)
- Default Branch: master
- Last Pushed: 2011-08-06T16:00:43.000Z (almost 14 years ago)
- Last Synced: 2024-10-13T02:50:41.588Z (7 months ago)
- Language: Ruby
- Homepage:
- Size: 184 KB
- Stars: 49
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.textile
- License: MIT-LICENSE
Awesome Lists containing this project
README
h1. LINK² "!https://secure.travis-ci.org/grimen/link2.png!":http://travis-ci.org/grimen/link2
_Generation next *link_to*-helper for Rails: Spiced with intelligence, and semantic beauty._
h2. Introduction
A better link helper for Rails designed with the principle of making smart assumptions based on what's known to avoid repeated and unnecessary code declarations; and at the same time making the code more semantic/readable/beautiful (my subjective opinion). On top of that - for even more maintainable views - scoped I18n translations without lean defaults for fast prototyping. WIN-WIN-WIN.
*Helpers:*
* *@link_to@* enhanced by @link@
* *@button_to@* enhanced by @button@This is *not* a re-implementation of these helpers; rather it wraps these but parses the specified method arguments and extracts as much known information as possible to fill in the missing pieces. The core helpers are not altered at all: You can call them old-school like there was no tomorrow (after using Link2 for a while you'll spoiled and the core helpers will feel so yesterday, really).
*Goals/Features:*
* *Rapid & flexible* - prototyping-friendly link helpers - with no trade-offs, really.
* *DRY* - based on specified arguments: Use what's know to make smart assumptions for more readable and maintainable view code.
* *I18n deluxe* - Lookup scoped translations based on action, model, etc., for more flexible translations - with lean defaults. Enhanced with some nifty interpolation features as well. Code first, translate later.
* *DOM Selectors* - Why defining DOM classes for RESTful links all the time when same patterns occur? Optionally DONE.
* *Stable* - Full test-coverage for stability. Unit + Rails integration tests, check: @59 tests: all passed@
* *Maintainable* - Well-documented code.h2. Installation
"Drop a *Gem* on 'em":http://open.spotify.com/track/2pqKuHtn8ZKMMMqbJrA2e7:
$ sudo gem install link2*Dependencies:*
* *"rails 2.3.x":http://github.com/rails/rails* only. Might as well work with Rails 3 already, but I didn't write that.
For testing: test-unit, "mocha":http://github.com/floehopper/mocha, and "webrat":http://github.com/brynary/webrat. Optional: "leftright":http://github.com/jordi/leftright
h2. Setup
Generate *initializer* (optional):
$ ./script/generate link2
create config/initializers/link2.rbh2. Usage
*A few examples* using the spiced up @link_to@/@button_to@ helpers, using our trusty fellow *Post* class:
link "No operation"
# => link_to 'No operation', '#'link 'http://bash.org'
# => link_to 'http://bash.org', 'http://bash.org'link "Hilarious", 'http://bash.org'
# => link_to 'Hilarious', 'http://bash.org'link :home, '/intro'
# => link_to I18n.t(:home, ...), '/intro'link :home
# => link_to I18n.t(:home, ...), root_pathlink :back
# => link_to I18n.t(:home, ...), :backlink :index
# => link_to I18n.t(:index, ...), posts_path # Note: auto-detectedlink :trash
# => link_to I18n.t(:trash, ...), trash_post_path(@post) # Note: auto-detectedlink :new
# => link_to I18n.t(:new, ...), new_post_path(:id => @post.id) # Note: auto-detected, id for current resource - if found - passed, makes the implementation more genericlink @post
# => link_to I18n.t(:show, ...), post_path(@post)link [@post, @comment]
# => link_to I18n.t(:show, ...), post_comment_path(@post, @comment)link :go_back, :back
# => link_to I18n.t(:go_back, ...), :backlink :new, :post
# => link_to I18n.t(:new, ...), new_post_pathlink :new, Post
# => link_to I18n.t(:new, ...), new_post_pathlink :new, @post
# => link_to I18n.t(:new, ...), new_post_path(:id => @post.id) # ...if you think about it; useful for cloning.link :edit, @post
# => link_to I18n.t(:edit, ...), edit_post_path(@post)link :edit, [@post, @comment]
# => link_to I18n.t(:edit, ...), edit_post_comment_path(@post, @comment)link :kick, @post
# => link_to I18n.t(:kick, ...), kick_post_path(@post)link "All items", :index
# => link_to "All items", posts_path # Note: auto-detected, see abovelink "New one!", :new, Post
# => link_to "New one!", new_post_pathlink :new, UserSession { image_tag('sign_in_button.png') }
# => link_to image_tag('sign_in_button.png'), new_user_session_path...
Same works for @button@, and you also can optionally use the branded aliases: @link2@ and @button2@.
h2. URL + HTML Options
Link2 link helpers accept options in the same way as the core helpers @link_to@ and @button_to@: first @options@ (a.k.a. @url_options@) and then @html_options@. See the "Rails core UrlHelpers documentation":http://railsapi.com/doc/rails-v2.3.5/classes/ActionView/Helpers/UrlHelper.html#M002452 for details on this. Link2 helpers just pass any non-Link2-related options to the Rails core helpers. In other words no need to learn a new API; just pass the needed options like in the past.
h2. Expected arguments (...but the examples should be enough)
A summary of the expected argument flavors if the examples for the curious minds:
link(label, options = {}, html_options = {})
link(url, options = {}, html_options = {}, &content_block)
link(resource, options = {}, html_options = {}, &content_block)link(label, url, options = {}, html_options = {})
link(action, resource, options = {}, html_options = {}, &content_block)link(label, action, resource)
Same applies to the @button@ helper, naturally.
h2. I18n
Link2 was designed with the power of I18n in mind; following certain lookup patterns to make it easier to manage link-translations even as your Rails-app grows. This is how in short:
*1. Lookup scopes* (Optional)
This is the default lookup order, in priority order:
Link2.setup do |config|
config.i18n_scopes = [
'{{models}}.links.{{action}}',
'links.{{action}}'
]
endValid lookup scope interpolations:
* @model@ - link model name, e.g. CaptainMorgan / @captain_morgan => "captain_morgan"
* @models@ - pluralized link model name, e.g. CaptainMorgan / @captain_morgan => "captain_morgans"
* @controller@ - current controller name
* @action@ - the link action name*2. Translations* (Optional)
en:
links:
order: "Bartender!!"
drink: "Drink your {{resource}} now"
captain_morgans:
links:
order: "New barrel of rum with lime, ohoy!"
drink: "Slurp {{name}} like a pirate"Valid value interpolations:
* @resource@ - resource humanized name (parsed with I18n if possible), e.g. CaptainMorgan / @captain_morgan => "captain morgan"
* @resources@ - pluralized resource humanized name (parsed with I18n if possible), e.g. CaptainMorgan / @captain_morgan => "captain morgans"
* @name@ - current resource name to_s-value, e.g. @captain_morgan.to_s => "Captain Morgan with Cola and lime #4"*3. Label parsing* (Optional)
Customize @to_s@ for your model(s) to return a more humane string.
class CaptainMorgan < ActiveRecord::Base
def to_s
"Captain ##{self.id}"
end
end*4. Go*
Now - with the config and translations setup - let the unicorn free:
link :order, Caipirinha
# => link_to "Bartender!!", new_caipirinha_pathlink :drink, @sour_caipirinha
# => link_to "Drink your caipirinha now", drink_caipirinha_path(@sour_caipirinha)link :order, CaptainMorgan
# => link_to "New barrel of rum with lime, ohoy!", new_captain_morgan_pathlink :drink, @captain_morgan_no_8
# => link_to "Slurp Captain #8 like a pirate", drink_captain_morgan_path(@captain_morgan_no_8) # See: CaptainMorgan#to_sh2. DOM Selectors
To make a web-designer's life easier Link2 generates some semantic selector classes based on specified/known link properties for easier DOM-manipulation with CSS and javascript.
*Examples:*
link :new, Post
# => ...link :edit, @post_14
# => ...link :back
# => ......
*Configuration:*
This behavior is enabled by default but can be disabled just in case; preferably in the initializer:
Link2.setup do |config|
config.dom_selectors = false
endh2. The other fellows...
*@link_to_function@*
To get the Link2 features for @link_to_function@ - which is *deprecated in Rails 3* because of it's obtrusive nature (note: obtrusive should be avoided) - you can get such behaviour with Link2 (if you must) by specifying @:onclick@ HTML attribute like so:
link :hello, :onclick => "alert('Hello world!')"*@link_to_remote@*
No Link2-wrapper for this one. Also, it's *deprecated in Rails 3* as well for same reasons as above. In Rails 3 it should be possible to call it like so:
link :hello, say_hello_path(@world), :remote => true...but as Link2 is *not tested with Rails 3* yet; use the old-school @link_to@ for now.
*@link_to_if@ + @link_to_unless@*
I didn't extend the behavior for the helpers @link_to_if@ and @link_to_unless@ because I simply think they should not be used in Rails apps; my strong opinion is that they introduce unnecessary complexity in code and make it less readable. I also skipped @link_to_if_current@ because it's not very thorough implementation - even an extra URI slash make it confused, which is funny. Hate it, or LOVE IT.
h2. Inspiration
I really like the "declarative_authorization":http://github.com/stffn/declarative_authorization view helper DSL for checking permissions on models, and brought the pattern to the link helpers - they are like *ying & yang*:
link(:edit, @account) if permitted_to?(:edit, @account)...but I usually mix it with an alias:
link(:edit, @account) if can?(:edit, @account)Nice, huh? =)
h2. TODO
See "TODO":http://github.com/grimen/link2/blob/master/TODO
h2. License
Released under the MIT license.
Copyright (c) "Jonas Grimfelt":http://github.com/grimen