Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add page_description helper, refactor internals #47

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
65 changes: 36 additions & 29 deletions README.md
Expand Up @@ -3,55 +3,60 @@ Flutie

[![Build Status](https://secure.travis-ci.org/thoughtbot/flutie.png)](http://travis-ci.org/thoughtbot/flutie)

Flutie provides extra ActionView view helpers for use with Rails applications. Previous versions created default application styles.
Flutie is a Rails Engine that provides common `ActionView` view helpers.
It works with Rails > 3.0.

Please look to [Bourbon](https://github.com/thoughtbot/bourbon) and [Neat](https://github.com/thoughtbot/neat) gems for style defaults now.
Previous versions created default application styles. We now use
[Bourbon](https://github.com/thoughtbot/bourbon) and
[Neat](https://github.com/thoughtbot/neat) styles.

Installation & Upgrading
------------------------

Flutie is a Railtie meant for use with Rails. It works with versions of Rails greater than 3.0.
Install
-------

Flutie is recommended to be run as a gem and included in your Gemfile:
Add Flutie to your Gemfile:

gem 'flutie'

Helpers
-------

Flutie provides several helper methods for layouts as well.

#### page_title

The `page_title` method can be used like:

<title><%= page_title %></title>
The `page_title` and `page_description` methods can be used like:

By default, it will produce results like:
<%= page_description %>
<%= page_title %>

<title>Appname : page title</title>
By default, Flutie will create empty tags:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have to look at the HTML spec, but I believe that the title element cannot be empty.

I realize the intention of flutie is to have a reasonable default and assume that the user would override the default, but it seems weird to generate invalid html by default.

That was part of the motivation of the previous impl using the Rails app name (which, granted, is usually not a good page title, but was the least bad thing I could think of).


* "App name" comes from the module name of the rails application created by your app, i.e. `Appname::Application` will produce "Appname"
* "page" comes from trying `content_for(:page_title)` and assumes you are using `content_for` with `:page_title` symbol on your pages.
* The separator defaults to " : "
<meta name="description" content="">
<title></title>

These can be overridden by passing an options hash including `:app_name`, `:page_title_symbol` and `:separator` hash keys, ie:
Define your page titles and descriptions using [Rails
internationalization][i18n]:

content_for(:site_page_title, 'My title of my page')
page_title(:app_name => 'My app name', :page_title_symbol => :site_page_title, :separator => " | ")
=> "My app name | My title of my page"
[i18n]: http://guides.rubyonrails.org/i18n.html

#### body_class
en:
projects:
new:
page_title:
New Project
edit:
page_description:
'%{project.description}'
page_title:
'Edit %{project}'

The `body_class` method can be used like:

<body class="<%= body_class %>">

This will produce a string including the controller name and controller-action name. For example, The WidgetsController#show action would produce:
This will produce a string including the controller name and controller-action
name. For example, The `WidgetsController#show` action would produce:

<body class="widgets widgets-show">

Anything which has been added via `content_for(:extra_body_classes)` will be added to the end, for example:
Anything which has been added via `content_for(:extra_body_classes)` will be
added to the end, for example:

content_for(:extra_body_classes, 'special-page')
<body class="<%= body_class %>">
Expand All @@ -67,13 +72,15 @@ Credits

![thoughtbot](http://thoughtbot.com/images/tm/logo.png)

Flutie is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
Flutie is maintained and funded by [thoughtbot, inc](http://thoughtbot.com).

Thank you to all [the contributors](https://github.com/thoughtbot/flutie/contributors)!
Thank you to all [the
contributors](https://github.com/thoughtbot/flutie/contributors)!

The names and logos for thoughtbot are trademarks of thoughtbot, inc.

License
-------

Flutie is Copyright © 2010-2013 thoughtbot. It is free software, and may be redistributed under the terms specified in the LICENSE file.
Flutie is Copyright © 2010-2014 thoughtbot. It is free software, and may be
redistributed under the terms specified in the LICENSE file.
31 changes: 31 additions & 0 deletions app/helpers/flutie/view_helper.rb
@@ -0,0 +1,31 @@
module Flutie
module ViewHelper
def body_class
basic_body_class = "#{controller_name} #{controller_name}-#{action_name}"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this generate something like admin_users-index? Not sure if we care about _ and - inconsistency.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that controller_name method solves this issue.


if content_for?(:extra_body_classes)
[basic_body_class, content_for(:extra_body_classes)].join(' ')
else
basic_body_class
end.gsub('/', '-')
end

def page_title
content_tag :title, translate_by_controller_action(:page_title)
end

def page_description
tag :meta,
{
content: translate_by_controller_action(:page_description),
name: 'description'
},
true
end

def translate_by_controller_action(tag)
key = [controller_name, action_name, tag].join('.').gsub('/', '-')
I18n.t(key, default: '')
end
end
end
4 changes: 3 additions & 1 deletion lib/flutie.rb
@@ -1,5 +1,7 @@
require 'flutie/version'
require 'rails/engine'
require 'flutie/engine'
require 'helpers/flutie/view_helper'

module Flutie
require 'flutie/railtie' if defined?(Rails)
end
13 changes: 0 additions & 13 deletions lib/flutie/body_class_helper.rb

This file was deleted.

4 changes: 4 additions & 0 deletions lib/flutie/engine.rb
@@ -0,0 +1,4 @@
module Flutie
class Engine < Rails::Engine
end
end
13 changes: 0 additions & 13 deletions lib/flutie/page_title_helper.rb

This file was deleted.

19 changes: 0 additions & 19 deletions lib/flutie/railtie.rb

This file was deleted.

103 changes: 103 additions & 0 deletions spec/helpers/view_helper_spec.rb
@@ -0,0 +1,103 @@
require 'rspec/expectations'
require 'i18n'
require 'action_view'
require File.expand_path('../../../app/helpers/flutie/view_helper', __FILE__)

module Flutie
module Stubs
def stub_controller_action(controller, action)
helper.stub(controller_name: controller, action_name: action)
helper.stub(content_for?: false)
end

def store_translations(translations)
I18n.backend.store_translations(:en, translations)
end

def helper
@helper ||= Class.new { include Flutie::ViewHelper }.new
end
end

module ViewHelper
include ActionView::Helpers::TagHelper
end
end

RSpec.configure do |config|
config.include Flutie::Stubs
config.include RSpec::Matchers
config.mock_framework = :rspec
end

describe Flutie::ViewHelper do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to put this in its own file, but maybe that's for another PR?

describe '#body_class' do
it 'handles normal controllers' do
stub_controller_action('widgets', 'show')

result = helper.body_class

expect(result).to eq 'widgets widgets-show'
end

it 'handles nested controllers' do
stub_controller_action('module/widgets', 'show')

result = helper.body_class

expect(result).to eq 'module-widgets module-widgets-show'
end

it 'handles extra body classes set via content_for' do
stub_controller_action(:widgets, :show)
helper.stub(content_for?: true)
helper.stub(content_for: 'extra classes')

result = helper.body_class

expect(result).to eq 'widgets widgets-show extra classes'
end
end

describe '#page_title' do
it 'is blank by default' do
stub_controller_action('widgets', 'show')
store_translations({})

result = helper.page_title

expect(result).to eq '<title></title>'
end

it "uses the page's i18n locale when present" do
stub_controller_action('widgets', 'show')
store_translations(widgets: { show: { page_title: 'Widgets are fun' } })

result = helper.page_title

expect(result).to eq '<title>Widgets are fun</title>'
end
end

describe '#page_description' do
it 'is blank by default' do
stub_controller_action('widgets', 'show')
store_translations({})

result = helper.page_description

expect(result).to eq '<meta content="" name="description">'
end

it "uses the page's i18n locale when present" do
stub_controller_action('widgets', 'show')
store_translations(
widgets: { show: { page_description: 'Widgets are fun' } }
)

result = helper.page_description

expect(result).to eq '<meta content="Widgets are fun" name="description">'
end
end
end