1
0
Fork 0
forked from OpenNeo/impress

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 75be12fe2e
commit 132a49d30b
16 changed files with 297 additions and 114 deletions

View file

@ -1,8 +1,12 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include FragmentLocalization
protect_from_forgery protect_from_forgery
helper_method :can_use_image_mode?, :user_is? helper_method :can_use_image_mode?, :user_is?
before_filter :set_locale
def authenticate_user! # too lazy to change references to login_path def authenticate_user! # too lazy to change references to login_path
redirect_to(login_path) unless user_signed_in? redirect_to(login_path) unless user_signed_in?
end end
@ -15,6 +19,18 @@ class ApplicationController < ActionController::Base
true true
end 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') def not_found(record_name='record')
raise ActionController::RoutingError.new("#{record_name} not found") raise ActionController::RoutingError.new("#{record_name} not found")
end end
@ -31,6 +47,10 @@ class ApplicationController < ActionController::Base
redirect_to(params[:return_to] || default) redirect_to(params[:return_to] || default)
end end
def set_locale
I18n.locale = infer_locale || I18n.default_locale
end
def user_is?(user) def user_is?(user)
user_signed_in? && user == current_user user_signed_in? && user == current_user
end end

View file

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

View file

@ -1,4 +1,6 @@
module ApplicationHelper module ApplicationHelper
include FragmentLocalization
def absolute_url(path_or_url) def absolute_url(path_or_url)
if path_or_url.include?('://') # already an absolute URL if path_or_url.include?('://') # already an absolute URL
path_or_url path_or_url
@ -97,6 +99,11 @@ module ApplicationHelper
end) end)
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 def login_path_with_return_to
login_path :return_to => request.fullpath login_path :return_to => request.fullpath
end end
@ -150,5 +157,14 @@ module ApplicationHelper
def title(value) def title(value)
content_for :title, value content_for :title, value
end 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 end

View file

@ -2,13 +2,17 @@ module ContributionHelper
def contributed_description(contributed, image = true) def contributed_description(contributed, image = true)
case contributed case contributed
when Item when Item
contributed_item(contributed, image, 'for the first time') suffix = translate_contributed_description('item_suffix')
contributed_item(contributed, image, suffix)
when SwfAsset 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 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 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
end end
@ -41,4 +45,8 @@ module ContributionHelper
def output(&block) def output(&block)
raw([].tap(&block).join(' ')) raw([].tap(&block).join(' '))
end end
def translate_contributed_description(key)
translate "contributions.contributed_description.#{key}"
end
end end

View file

@ -3,6 +3,14 @@ module OutfitsHelper
hidden_field_tag 'destination', value, :id => nil hidden_field_tag 'destination', value, :id => nil
end 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={}) def link_to_edit_outfit(content_or_outfit, outfit_or_options, options={})
if block_given? if block_given?
content = capture_haml(&Proc.new) content = capture_haml(&Proc.new)

View file

@ -1,16 +1,12 @@
class ContributionObserver < ActiveRecord::Observer class ContributionObserver < ActiveRecord::Observer
include FragmentExpiration
def after_create(contribution) 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' if contribution.contributed_type == 'SwfAsset'
item = contribution.contributed.item item = contribution.contributed.item
controller.expire_fragment("items/#{item.id} contributors") expire_fragment("items/#{item.id} contributors")
end end
end end
private
def controller
@controller ||= ActionController::Base.new
end
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 class ItemObserver < ActionController::Caching::Sweeper
include FragmentExpiration
def after_create(item) def after_create(item)
Rails.logger.debug "Item #{item.id} was just created" Rails.logger.debug "Item #{item.id} was just created"
expire_newest_items expire_newest_items
@ -16,18 +18,14 @@ class ItemObserver < ActionController::Caching::Sweeper
private private
def controller
@controller ||= ActionController::Base.new
end
def expire_cache_for(item) def expire_cache_for(item)
controller.expire_fragment("items/#{item.id}#item_link_partial") expire_fragment("items/#{item.id}#item_link_partial")
controller.expire_fragment("items/#{item.id} header") expire_fragment("items/#{item.id} header")
controller.expire_fragment("items/#{item.id} info") expire_fragment("items/#{item.id} info")
end end
def expire_newest_items def expire_newest_items
controller.expire_fragment('outfits#new newest_items') expire_fragment_in_all_locales('outfits#new newest_items')
controller.expire_fragment('items#index newest_items') expire_fragment('items#index newest_items')
end end
end end

View file

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

View file

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

View file

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

@ -3967,6 +3967,10 @@ body.outfits-new #latest-contribution #recent-contributions-link {
margin-right: 0.5em; margin-right: 0.5em;
} }
/* line 207, ../../../app/stylesheets/outfits/_new.sass */ /* 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 { body.outfits-new #latest-contribution #latest-contribution-created-at {
color: #448844; color: #448844;
margin-left: 0.5em; margin-left: 0.5em;