i18n for outfits#new (and layouts#application), including caching

This commit is contained in:
Emi Matchu 2012-12-30 01:46:36 -05:00
parent df5c7fe3d4
commit 744c10495d
16 changed files with 297 additions and 114 deletions

View file

@ -1,7 +1,11 @@
class ApplicationController < ActionController::Base
include FragmentLocalization
protect_from_forgery
helper_method :can_use_image_mode?, :user_is?
before_filter :set_locale
def authenticate_user! # too lazy to change references to login_path
redirect_to(login_path) unless user_signed_in?
@ -15,6 +19,18 @@ class ApplicationController < ActionController::Base
true
end
# This locale-inferrence method is designed for debugging. Once we're ready
# for production, we'll probably start inferring from domain.
def infer_locale
inference = params[:locale]
inference if inference && I18n.available_locales.include?(inference.to_sym)
end
def localized_fragment_exist?(key)
localized_key = localize_fragment_key(key, locale)
fragment_exist?(localized_key)
end
def not_found(record_name='record')
raise ActionController::RoutingError.new("#{record_name} not found")
end
@ -30,6 +46,10 @@ class ApplicationController < ActionController::Base
def redirect_back!(default=:back)
redirect_to(params[:return_to] || default)
end
def set_locale
I18n.locale = infer_locale || I18n.default_locale
end
def user_is?(user)
user_signed_in? && user == current_user

View file

@ -48,20 +48,16 @@ class OutfitsController < ApplicationController
end
def new
unless fragment_exist?(:action_suffix => 'start_from_scratch_form_content')
unless localized_fragment_exist?(:action_suffix => 'start_from_scratch_form_content')
@colors = Color.all_ordered_by_name
@species = Species.all_ordered_by_name
end
unless fragment_exist?(:action_suffix => 'top_contributors')
@top_contributors = User.top_contributors.limit(User::PreviewTopContributorsCount)
end
unless fragment_exist?('outfits#new newest_items')
unless localized_fragment_exist?('outfits#new newest_items')
@newest_items = Item.newest.select([:id, :name, :thumbnail_url]).limit(9)
end
unless fragment_exist?('outfits#new latest_contribution')
unless localized_fragment_exist?('outfits#new latest_contribution')
@latest_contribution = Contribution.recent.first
Contribution.preload_contributeds_and_parents([@latest_contribution])
end

View file

@ -1,4 +1,6 @@
module ApplicationHelper
include FragmentLocalization
def absolute_url(path_or_url)
if path_or_url.include?('://') # already an absolute URL
path_or_url
@ -96,6 +98,11 @@ module ApplicationHelper
html + javascript_include_tag(JAVASCRIPT_LIBRARIES[name])
end)
end
def localized_cache(key, &block)
localized_key = localize_fragment_key(key, locale)
cache(localized_key, &block)
end
def login_path_with_return_to
login_path :return_to => request.fullpath
@ -150,5 +157,14 @@ module ApplicationHelper
def title(value)
content_for :title, value
end
def userbar_contributions_summary(user)
contributions_link_content = translate('.userbar.contributions_link_content',
:user_points => user.points)
contributions_link = link_to(contributions_link_content,
user_contributions_path(user))
translate '.userbar.contributions_summary_html',
:contributions_link => contributions_link
end
end

View file

@ -2,13 +2,17 @@ module ContributionHelper
def contributed_description(contributed, image = true)
case contributed
when Item
contributed_item(contributed, image, 'for the first time')
suffix = translate_contributed_description('item_suffix')
contributed_item(contributed, image, suffix)
when SwfAsset
contributed_item(contributed.item, image, 'on a new body type')
suffix = translate_contributed_description('swf_asset_suffix')
contributed_item(contributed.item, image, suffix)
when PetType
contributed_pet_type(contributed, image, :after => 'for the first time')
suffix = translate_contributed_description('pet_type_suffix')
contributed_pet_type(contributed, image, :after => suffix)
when PetState
contributed_pet_type(contributed.pet_type, image, :before => 'a new pose for')
prefix = translate_contributed_description('pet_state_prefix')
contributed_pet_type(contributed.pet_type, image, :before => prefix)
end
end
@ -41,4 +45,8 @@ module ContributionHelper
def output(&block)
raw([].tap(&block).join(' '))
end
def translate_contributed_description(key)
translate "contributions.contributed_description.#{key}"
end
end

View file

@ -2,6 +2,14 @@ module OutfitsHelper
def destination_tag(value)
hidden_field_tag 'destination', value, :id => nil
end
def latest_contribution_description(contribution)
user = contribution.user
contributed = contribution.contributed
t 'outfits.new.latest_contribution_description_html',
:user_link => link_to(user.name, user_contributions_path(user)),
:contributed_description => contributed_description(contributed, false)
end
def link_to_edit_outfit(content_or_outfit, outfit_or_options, options={})
if block_given?

View file

@ -1,16 +1,12 @@
class ContributionObserver < ActiveRecord::Observer
include FragmentExpiration
def after_create(contribution)
controller.expire_fragment('outfits#new latest_contribution')
expire_fragment_in_all_locales('outfits#new latest_contribution')
if contribution.contributed_type == 'SwfAsset'
item = contribution.contributed.item
controller.expire_fragment("items/#{item.id} contributors")
expire_fragment("items/#{item.id} contributors")
end
end
private
def controller
@controller ||= ActionController::Base.new
end
end

View file

@ -0,0 +1,18 @@
module FragmentExpiration
include FragmentLocalization
delegate :expire_fragment, :to => :controller
def expire_fragment_in_all_locales(key)
I18n.available_locales.each do |locale|
localized_key = localize_fragment_key(key, locale)
expire_fragment(localized_key)
end
end
private
def controller
@controller ||= ActionController::Base.new
end
end

View file

@ -0,0 +1,11 @@
module FragmentLocalization
def localize_fragment_key(key, locale)
if key.is_a?(Hash)
{:locale => locale}.merge(key)
elsif key.is_a?(String)
"#{key} #{locale}"
else
raise TypeError, "unexpected fragment key type: #{key.class}"
end
end
end

View file

@ -1,4 +1,6 @@
class ItemObserver < ActionController::Caching::Sweeper
include FragmentExpiration
def after_create(item)
Rails.logger.debug "Item #{item.id} was just created"
expire_newest_items
@ -16,18 +18,14 @@ class ItemObserver < ActionController::Caching::Sweeper
private
def controller
@controller ||= ActionController::Base.new
end
def expire_cache_for(item)
controller.expire_fragment("items/#{item.id}#item_link_partial")
controller.expire_fragment("items/#{item.id} header")
controller.expire_fragment("items/#{item.id} info")
expire_fragment("items/#{item.id}#item_link_partial")
expire_fragment("items/#{item.id} header")
expire_fragment("items/#{item.id} info")
end
def expire_newest_items
controller.expire_fragment('outfits#new newest_items')
controller.expire_fragment('items#index newest_items')
expire_fragment_in_all_locales('outfits#new newest_items')
expire_fragment('items#index newest_items')
end
end

View file

@ -203,6 +203,9 @@ body.outfits-new
#recent-contributions-link
font-weight: bold
margin-right: .5em
&::after
content: ":"
#latest-contribution-created-at
color: $soft-text-color

View file

@ -8,7 +8,7 @@
- if content_for? :title_category
= yield :title_category
- else
Dress to Impress: Preview customized Neopets' clothing and wearables
#{t 'app_name'}: #{t '.title_tagline'}
/[if IE]
= include_javascript_libraries :html5
= yield :stylesheets
@ -34,45 +34,34 @@
- if home_link?
%a#home-link{:href => root_path}
%span Dress to Impress
%span= t 'app_name'
#userbar
- if user_signed_in?
%span
Hey, #{current_user.name}!
You have
= succeed '.' do
= link_to "#{current_user.points} points", user_contributions_path(current_user)
= link_to 'Items', user_closet_hangers_path(current_user), :id => 'userbar-items-link'
= link_to 'Outfits', current_user_outfits_path
= link_to 'Settings', Openneo::Auth.remote_settings_url
= link_to 'Log out', logout_path_with_return_to
= t '.userbar.greeting', :user_name => current_user.name
= userbar_contributions_summary(current_user)
= link_to t('.userbar.items'), user_closet_hangers_path(current_user), :id => 'userbar-items-link'
= link_to t('.userbar.outfits'), current_user_outfits_path
= link_to t('.userbar.settings'), Openneo::Auth.remote_settings_url
= link_to t('.userbar.logout'), logout_path_with_return_to
- else
= link_to login_path_with_return_to, :id => 'userbar-log-in' do
= image_tag auth_server_icon_url
%span Log in
%span= t('.userbar.login')
#footer
%ul
%li
%a{:href => "http://openneo.net/", :target => "_blank"} OpenNeo
%li
%a{:href => "http://blog.openneo.net/", :target => "_blank"} Blog
%li
%a{:href => "http://forum.openneo.net/", :target => "_blank"} Forum
%li
%a{:href => "http://github.com/matchu/openneo-impress-rails"} Source Code
%li
%a{:href => terms_path} Terms of Use
%li= link_to t('organization_name'), 'http://openneo.net/'
%li= link_to t('.footer.blog'), 'http://blog.openneo.net/'
%li= link_to t('.footer.source_code'),
'http://github.com/matchu/openneo-impress-rails'
%li= link_to t('.footer.terms'), terms_path
%div
Contact:
#{t('.footer.contact')}:
%ul
%li
%a{:href => feedback_url} Suggestions
%li
%a{:href => "mailto:#{contact_email}"} Questions, comments, bugs
%p
Images &copy; 2000&ndash;#{Date.today.year} Neopets, Inc. All Rights Reserved.
Used With Permission
%li= link_to t('.footer.suggestions'), feedback_url
%li= mail_to contact_email, t('.footer.email')
%p= t '.footer.copyright', :year => Date.today.year
= yield(:javascripts)

View file

@ -3,100 +3,86 @@
= campaign_progress
#outfit-forms
- cache :action_suffix => 'outfit_forms_intro' do
- localized_cache :action_suffix => 'outfit_forms_intro' do
#pet-preview
= image_tag 'default_preview.png', :alt => ''
%span
%h1 Dress to Impress
%h2 Neopets wearables made easy!
%h1= t 'app_name'
%h2= t '.tagline'
= form_tag load_pet_path, :id => 'load-pet-to-wardrobe' do
- cache :action_suffix => 'main_load_pet_form_content' do
- localized_cache :action_suffix => 'main_load_pet_form_content' do
= origin_tag root_path
= destination_tag 'wardrobe'
%fieldset
%legend Enter your pet's name
%legend= t '.load_pet_legend'
= pet_name_tag :id => 'main-pet-name'
%button{:type => "submit"}
Plan my outfit!
= t '.load_pet_submit'
= form_tag wardrobe_path, :method => 'get', :id => 'start-from-scratch' do
- cache :action_suffix => 'start_from_scratch_form_content' do
- localized_cache :action_suffix => 'start_from_scratch_form_content' do
%fieldset
%legend Or start from scratch
%legend= t '.start_from_scratch_legend'
= pet_attribute_select 'color', @colors, 8
= pet_attribute_select 'species', @species
%input{:type => "submit", :value => "Go"}
%input{:type => "submit", :value => t('.start_from_scratch_submit')}
%ul#sections
- cache :action_suffix => 'your_items_module' do
- localized_cache :action_suffix => 'your_items_module' do
%li#your-items-module
= link_to image_tag('your_items.png'), your_items_path
%h3
= link_to 'Your Items', your_items_path
%h3= link_to t('your_items'), your_items_path
%div
%h4 Track and trade!
%p
Make lists of the items you own and want, and share them with the
world.
%h4= t '.your_items_tagline'
%p= t '.your_items_description'
= form_tag users_path, :method => 'get' do
= text_field_tag 'name', '', :placeholder => raw('find a user&hellip;'), :type => 'search'
= submit_tag 'search'
= text_field_tag 'name', '', :type => 'search',
:placeholder => t('.your_items_user_search_placeholder')
= submit_tag t('.your_items_user_search_submit')
- cache :action_suffix => 'infinite_closet_module' do
- localized_cache :action_suffix => 'infinite_closet_module' do
%li
%a{:href => items_path}
= image_tag 'items.png'
%h3
%a{:href => items_path}
Infinite Closet
= link_to image_tag('items.png'), items_path
%h3= link_to t('infinite_closet'), items_path
%div
%h4 Looking for something?
%p
Take a look through our wearables database!
%h4= t '.infinite_closet_tagline'
%p= t '.infinite_closet_description'
= form_tag items_path, :method => 'get' do
= text_field_tag 'q', '', :placeholder => raw('find an item&hellip;'), :type => 'search'
= submit_tag 'search'
= text_field_tag 'q', '', :type => 'search',
:placeholder => t('.infinite_closet_item_search_placeholder')
= submit_tag t('.infinite_closet_item_search_submit')
%li
%a{:href => bulk_pets_path}
= link_to bulk_pets_path do
= image_tag 'http://images.neopets.com/items/mall_ac_garland_spotlight.gif'
%h3
%a{:href => bulk_pets_path}
Modeling Hub
%h3= link_to t('modeling_hub'), bulk_pets_path
%div
%h4 Found something?
%p
Enter a pet's name here and we'll keep a copy of what it's wearing.
Thanks so much!
%h4= t '.modeling_hub_tagline'
%p= t '.modeling_hub_description'
= form_tag load_pet_path do
= origin_tag root_path
= pet_name_tag :placeholder => raw('model a pet&hellip;')
= submit_tag 'submit'
= pet_name_tag :placeholder => t('.modeling_hub_load_pet_placeholder')
= submit_tag t('.modeling_hub_load_pet_submit')
- cache 'outfits#new latest_contribution' do
- localized_cache 'outfits#new latest_contribution' do
#latest-contribution
= link_to 'Contributions:', contributions_path, :id => 'recent-contributions-link'
= link_to @latest_contribution.user.name, user_contributions_path(@latest_contribution.user)
showed us
= succeed '.' do
= contributed_description @latest_contribution.contributed, false
Thanks,
= succeed '!' do
= link_to @latest_contribution.user.name, user_contributions_path(@latest_contribution.user)
= link_to t('.latest_contribution_header'), contributions_path, :id => 'recent-contributions-link'
= latest_contribution_description(@latest_contribution)
%abbr#latest-contribution-created-at{:title => @latest_contribution.created_at.getutc.iso8601}
#whats-new
- cache :action_suffix => 'blog_preview' do
- localized_cache :action_suffix => 'blog_preview' do
#blog-preview
%h2
%div
%a#blog-preview-linkback{:href => 'http://blog.openneo.net/'} OpenNeo Blog
%a#blog-preview-linkback{:href => 'http://blog.openneo.net/'}
= t '.blog_linkback'
- cache 'outfits#new newest_items' do
- localized_cache 'outfits#new newest_items' do
#newest-items
%h2 New Items
%h2= t '.newest_items_header'
%ul
- @newest_items.each do |item|
= link_to image_tag(item.thumbnail_url), item

View file

@ -12,7 +12,7 @@ OpenneoImpressItems::Application.configure do
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = false
config.action_controller.perform_caching = true
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false

View file

@ -0,0 +1,67 @@
en-meep:
app_name: Dreep to Impreep
organization_name: OpenMeep
your_items: Your Meeps
infinite_closet: Infinite Meepit
modeling_hub: Meepiting Hub
layouts:
application:
title_tagline: Preview customized Neopets' meeps and meepits
userbar:
greeting: Meep, %{user_name}!
contributions_summary_html: You have %{contributions_link}.
contributions_link_content: "%{user_points} meeps"
items: Iteeps
outfits: Outfeeps
settings: Setteeps
logout: Meep out
login: Meep in
footer:
blog: Bleep
source_code: Source Meep
terms: Terms of Meep
contact: Meeptact
suggestions: Suggesteeps
email: Questions, comments, meepits
copyright:
Images © 2000%{year} Neopets, Inc. All Rights Reserved.
Used With Permission. Meep.
outfits:
new:
tagline: Meeps made meepy!
load_pet_legend: Enter your pet's meep
load_pet_submit: Meep my outfit!
start_from_scratch_legend: Or meep from scratch
start_from_scratch_submit: Meep
your_items_tagline: Meep and meep!
your_items_description:
Meep lists of the items you own and want, and meep them with the world.
your_items_user_search_placeholder: meep a user…
your_items_user_search_submit: meep
infinite_closet_tagline: Meeping for something?
infinite_closet_description: Take a meep through our wearables meep!
infinite_closet_item_search_placeholder: meep an item…
infinite_closet_item_search_submit: meep
modeling_hub_tagline: Found somemeep?
modeling_hub_description:
Meep a pet's meep here and we'll meep a meep of what it's wearing.
Thanks so meep!
modeling_hub_load_pet_placeholder: meep a pet…
modeling_hub_load_pet_submit: meep
latest_contribution_header: Contribumeeps
latest_contribution_description_html:
"%{user_link} meeped us %{contributed_description}.
Meep, %{user_link}!"
blog_linkback: OpenNeo Meep
newest_items_header: New Meeps
contributions:
contributed_description:
item_suffix: "for the first meep"
swf_asset_suffix: "on a new body meep"
pet_type_suffix: "for the first meep"
pet_state_prefix: "a new meep for"

View file

@ -1,5 +1,68 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"
app_name: Dress to Impress
organization_name: OpenNeo
your_items: Your Items
infinite_closet: Infinite Closet
modeling_hub: Modeling Hub
layouts:
application:
title_tagline: Preview customized Neopets' clothing and wearables
userbar:
greeting: Hey, %{user_name}!
contributions_summary_html: You have %{contributions_link}.
contributions_link_content: "%{user_points} points"
items: Items
outfits: Outfits
settings: Settings
logout: Log out
login: Log in
footer:
blog: Blog
source_code: Source Code
terms: Terms of Use
contact: Contact
suggestions: Suggestions
email: Questions, comments, bugs
copyright:
Images © 2000%{year} Neopets, Inc. All Rights Reserved.
Used With Permission
outfits:
new:
tagline: Neopets wearables made easy!
load_pet_legend: Enter your pet's name
load_pet_submit: Plan my outfit!
start_from_scratch_legend: Or start from scratch
start_from_scratch_submit: Go
your_items_tagline: Track and trade!
your_items_description:
Make lists of the items you own and want,
and share them with the world.
your_items_user_search_placeholder: find a user…
your_items_user_search_submit: search
infinite_closet_tagline: Looking for something?
infinite_closet_description: Take a look through our wearables database!
infinite_closet_item_search_placeholder: find an item…
infinite_closet_item_search_submit: search
modeling_hub_tagline: Found something?
modeling_hub_description:
Enter a pet's name here and we'll keep a copy of what it's wearing.
Thanks so much!
modeling_hub_load_pet_placeholder: model a pet…
modeling_hub_load_pet_submit: submit
latest_contribution_header: Contributions
latest_contribution_description_html:
"%{user_link} showed us %{contributed_description}.
Thanks, %{user_link}!"
blog_linkback: OpenNeo Blog
newest_items_header: New Items
contributions:
contributed_description:
item_suffix: "for the first time"
swf_asset_suffix: "on a new body type"
pet_type_suffix: "for the first time"
pet_state_prefix: "a new pose for"

View file

@ -3992,6 +3992,10 @@ body.outfits-new #latest-contribution #recent-contributions-link {
margin-right: 0.5em;
}
/* line 207, ../../../app/stylesheets/outfits/_new.sass */
body.outfits-new #latest-contribution #recent-contributions-link::after {
content: ":";
}
/* line 210, ../../../app/stylesheets/outfits/_new.sass */
body.outfits-new #latest-contribution #latest-contribution-created-at {
color: #448844;
margin-left: 0.5em;