SlideShare una empresa de Scribd logo
1 de 74
Descargar para leer sin conexión
Caching in a multi-
language environment
 Benjamin Krause <benjamin@omdb.org>
Caching in Rails
Caching in Rails
‣   Page Caching
‣   Action Caching
‣   Fragment Caching
Caching in Rails
‣ Page Caching
‣ ______________
  Action Caching
‣ Fragment Caching
Caching in Rails
    Page Caching           Fragment Caching

  routing                    routing               routing

before filters              before filters      before filters
 controller                 controller          controller
                  CACHED
 rendering                  rendering       parts CACHED

after filters               after filters        after filters


                                           illustration by Tammo Freese
Page Caching

               Webserver



File.exists?          !File.exists?



   __ _ ____
   ___ ___ _
   _ __ ____
   __ ___ __
                           Mongrel
   __ _ ____
Fragment Caching



Mongrel


Rendering   Fragment
             Cache
Caching in Rails
‣   No support for caching in different
    languages
‣   No support to expire all language-
    caches at once
‣   No support for language-negotiation
Content Negotiation
let the user decide, what he wants to see
Content Negotiation
consists of format negotiation and language
                negotiation
a simple resource
http://www.omdb.org/movies/2062
Format Negotiation

> HTTP “Accept” Header
  Accept: text/xml,application/xml,
          application/xhtml+xml,text/html

> Rails supports format negotiation
> Rails allows you to request a format
  explicitly (extra routes)
Format Negotiation
http://www.omdb.org/movies/2062.html
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Ratatouille</title>
    <meta http-equiv="Content-Type" content="text/html;
          charset=utf-8" />


http://www.omdb.org/movies/2062.xml
<?xml version="1.0" encoding="UTF-8"?>
<movie>
  <name>Ratatouille</name>
  <abstract>
    Remy is a rat, with a talent and passion for cooking.
    He dreams of one day working in a real restaurant
Format Negotiation


class MoviesController < ApplicationController
  def show
    respond_to do |format|
      format.html { render }
      format.xml { render :xml => @movie.to_xml }
      format.js   { render :json => @movie.to_json }
    end
  end
end
Language Negotiation


> HTTP “Accept-Language” Header
  Accept-Language: en-us,en;q=0.7,de;q=0.3

> Rails ignores the HTTP Header

> Rails doesn’t add language routes
Language Negotiation
Language Negotiation

http://www.omdb.org/movies/2062.html.en
Routing Error
no route found to match "/movies/2062.html.en" with
{:method=>:get}



http://www.omdb.org/movies/2062.xml.de
Routing Error
no route found to match "/movies/2062.xml.de" with
{:method=>:get}
let’s fix that
  extending Rails
Language Routes
extending Rails to set language routes
Language Routes

#   Adding default routes for
#   GET /movies/<id>
#   GET /movies/<id>.<format>
#   PUT /movies/<id>
#   PUT /movies/<id>.<format>
#   ...

map.resources :movies
map.resources :people
map.resources :casts
Language Routes
There are several possible routes, how to add a
language parameter.
http://www.omdb.org/movies/2062.html?lang=de
http://de.omdb.org/movies/2062.html
http://www.omdb.org/de/movies/2062.html
http://www.omdb.org/movies/2062.de.html
http://www.omdb.org/movies/2062.html.de
Language Routes
There are several possible routes, how to add a
language parameter.
http://www.omdb.org/movies/2062.html?lang=de
http://de.omdb.org/movies/2062.html
http://www.omdb.org/de/movies/2062.html
http://www.omdb.org/movies/2062.de.html
http://www.omdb.org/movies/2062.html.de
Language Routes
# Taken from Rails 1.2.3
# /actionpack-1.13.3/lib/action_controller/resources.rb
# with slight modifications to fit this slide :-)

action_options = action_options_for("show", resource)

map.named_route(
   "#{resource.name_prefix}#{resource.singular}",
   resource.member_path, action_options
)

map.named_route(
  "f_#{resource.name_prefix}#{resource.singular}",
  "#{resource.member_path}.:format", action_options
)
Language Routes
# Taken from Rails 1.2.3
# /actionpack-1.13.3/lib/action_controller/resources.rb
# with slight modifications to fit this slide :-)

action_options = action_options_for("show", resource)
   { :conditions   => { :method => :get },
     :requirements => { :id
map.named_route(                => /[^/;.,?]+/ },
     :action       => "show" }
   "#{resource.name_prefix}#{resource.singular}",
   resource.member_path, action_options
)

map.named_route(
  "f_#{resource.name_prefix}#{resource.singular}",
  "#{resource.member_path}.:format", action_options
)
Language Routes
# Taken from Rails 1.2.3
# /actionpack-1.13.3/lib/action_controller/resources.rb
# with slight modifications to fit this slide :-)

action_options = action_options_for("show", resource)
   { :conditions   => { :method => :get },
     :requirements => { :id
map.named_route(                => /[^/;.,?]+/ },
     :action       => "show" }
   "#{resource.name_prefix}#{resource.singular}",
   resource.member_path, action_options
)

map.named_route(
  "f_#{resource.name_prefix}#{resource.singular}",
  "#{resource.member_path}.:format", action_options
)            /movies/:id
Language Routes

#   Extending
#   ActionController::Resources::map_new_actions
#   ActionController::Resources::map_member_actions
#   and others to support a language parameter

map.named_route(
  "fl_#{resource.name_prefix}#{resource.singular}",
  "#{resource.member_path}.:format.:lang",
     action_options
)
Language Routes

#   Extending
#   ActionController::Resources::map_new_actions
#   ActionController::Resources::map_member_actions
#   and others to support a language parameter

map.named_route(
  "fl_#{resource.name_prefix}#{resource.singular}",
  "#{resource.member_path}.:format.:lang",
     action_options
)     { :conditions   => { :method   => :get },
        :requirements => { :id       => /[^/;.,?]+/
                           :lang     => /^fr|de|en$/ },
        :action       => "show" }
Language Routes
http://www.omdb.org/movies/2062.html.en
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Ratatouille</title>
    <meta http-equiv="Content-Type" content="text/html;
          charset=utf-8" />


http://www.omdb.org/movies/2062.xml.de
<?xml version="1.0" encoding="UTF-8"?>
<movie>
  <name>Ratatouille</name>
  <abstract>
    Remy is a rat, with a talent and passion for cooking.
    He dreams of one day working in a real restaurant
Accept-Language
extending Rails to know about the requested
                  language
Accept-Language


# in environment.rb
#
# These are custom extensions, this is not part
# of Rails

AC = ActionController
AC::AbstractRequest.default_language     = :en
AC::AbstractRequest.acceptable_languages = :fr, :de, :en
Accept-Language

# Taken from Rails 1.2.3
# /actionpack-1.13.3/lib/action_controller/request.rb

# Returns the accepted MIME type for the request
def accepts
  @accepts ||=
    if @env['HTTP_ACCEPT'].to_s.strip.empty?
      [ content_type, Mime::ALL ]
    else
      Mime::Type.parse(@env['HTTP_ACCEPT'])
    end
end
Accept-Language
class ActionController::AbstractRequest
  def accepts_languages
    begin
      @accepts_languages ||=
      @env['HTTP_ACCEPT_LANGUAGE'].split(",").collect {|l|
        l.gsub(/;.*$/, '').gsub(/-.*$/,'').downcase.to_sym
      }.push(default_language).uniq
      @accepts_languages.delete_if { |l|
        !acceptable_languages.include?(l)
      }
    rescue NoMethodError
      @accepts_languages =
        default_language.is_a?(Array) ?
          default_language : [ default_language ]
    end
  end
end
Accept-Language
Accept-Language: fr
=> [ :fr, :en ]
Accept-Language: fr; q=1.0, en; q=0.5, fi; q=0.2
=> [ :fr, :en ]
Accept-Language: en-us,en;q=0.7,de;q=0.3
=> [ :en, :de ]
Accept-Language: fi, es
=> [ :en ]
Accept-Language
class ActionController::AbstractRequest
  def language
    params[:lang] || accepts_languages.first
  end
end

class ApplicationController
  before_filter :set_language

  def set_language
    @language = session[:lang] || request.language
    # for Globalize:
    #   @language = Locale.set(@language)
    # for Gettext:
    #   params[:lang] = @language unless params[:lang]
  end
end
Language Routes
http://www.omdb.org/movies/2062.html.en
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Ratatouille</title>
    <meta http-equiv="Content-Type" content="text/html;
          charset=utf-8" />


http://www.omdb.org/movies/2062.xml.de
<?xml version="1.0" encoding="UTF-8"?>
<movie>
  <name>Ratatouille</name>
  <abstract>
    Eine Gourmet-Ratte muss so einiges erleiden,
    um ihre Lust auf exquisite Speisen befriedigen zu können.
Caching
view caching, that is
Page Caching
extending Rails to support language-based page
                    caching
Page Caching

               Webserver



File.exists?          !File.exists?



   __ _ ____
   ___ ___ _
   _ __ ____
   __ ___ __
                           Mongrel
   __ _ ____
Page Caching

class MoviesController < ApplicationController
  caches_page :show

  def show
    respond_to |format| do
      format.html { render }
      format.xml { render :xml => @movie.to_xml }
      format.js   { render :json => @movie.to_json }
    end
  end
end
Page Caching

   GET /movies/2062

          Mongrel




        caches_page



~/public/movies/2062.html
Page Caching

# Taken from Rails 1.2.3
# /actionpack-1.13.3/lib/action_controller/caching.rb

def cache_page(content = nil, options = {})
  return unless perform_caching && caching_allowed
  self.class.cache_page(content || response.body,
    url_for(options.merge(:only_path => true,
      :skip_relative_url_root => true,
      :format => params[:format])))
end
Page Caching

# Reimplementing the cache_page method

module ActionController::Caching::Pages
  def cache_page(content = nil, options = {})
    return unless perform_caching && caching_allowed
    self.class.cache_page(content || response.body,
      url_for(options.merge(:only_path => true,
        :skip_relative_url_root => true,
        :format => params[:format],
        :lang   => request.language)))
  end
end
Page Caching

     GET /movies/2062

            Mongrel




          caches_page



~/public/movies/2062.html.en
Page Caching


curl http://www.omdb.org/movies/2062 
              -H 'Accept: application/xml'


=> ~/public/movies/2062.xml.en
Page Caching


curl http://www.omdb.org/movies/2062 
             -H 'Accept-Language: fr, en, de'


=> ~/public/movies/2062.html.fr
Page Caching


curl http://www.omdb.org/movies/2062 
            -H 'Accept-Language: fr, en, de' 
            -H 'Accept: application/xml'

=> ~/public/movies/2062.xml.fr
Apache
how-to use Apaches content negotiations
Apache

# Taken from
# http://mongrel.rubyforge.org/docs/apache.html

# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]

# Redirect all non-static requests to cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI}
                                           [P,QSA,L]
Apache


# Taken from
# http://bugs.omdb.org/browser/trunk/conf/webserver/apache.conf

# Perform content-negotiation and send to mongrel
# if not cached.
RewriteCond %{DOCUMENT_ROOT}/%{LA-U:REQUEST_URI} !-f
RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI}
                                           [P,QSA,L]
Apache

Apache 2.2 mod_rewrite documentation:

%{LA-U:variable} can be used for look-aheads
which perform an internal (URL-based)
sub-request to determine the final value of
variable.
Apache
# Prefer text/html over other Accept Headers
# Simplified RewriteConditions
RewriteCond %{HTTP_ACCEPT} text/html
RewriteCond %{SCRIPT_FILENAME} !.html$
RewriteCond %{IS_SUBREQ} 'false'
RewriteRule ^/(.*)$ /%{SCRIPT_FILENAME}.html [QSA]

# Perform content-negotiation and send to mongrel
# if not cached.
RewriteCond %{DOCUMENT_ROOT}/%{LA-U:REQUEST_URI} !-f
RewriteCond %{IS_SUBREQ} 'false'
RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI}
                                           [P,QSA,L]
GET /movies/2062                      Apache

                                      Subrequest

                                  Apache
/movies/2062.html.en         Content Negotiation

                       File.exists?          !File.exists?


                       __ ___ __ _
                       __ __ __ __
                       ___ __ __ _
                        _ __ ___ __             Mongrel
                       ___ __ _ _ _
                       __ __ _ _ __
Apache



# Let the user change the language in your
# application

SetEnvIf Cookie "language=(..)" prefer-language=$1
Fragment Caching
extending Rails to support language-based
           fragment caching
Fragment Caching

<% cache do %>
  <div class="person">
    <div class="image">
      <%= img_tag image_url(cast.person.image) %>
    </div>
    <strong>
      <%= link_to cast.person.name,
                  person_url(cast.person) %>
    </strong>
  </div>
<% end %>
Fragment Caching

   cached content




      MemCache
Fragment Caching

<% cache :lang => request.language do %>
  <div class="person">
    <div class="image">
      <%= img_tag image_url(cast.person.image) %>
    </div>
    <strong>
      <%= link_to cast.person.name,
                  person_url(cast.person) %>
    </strong>
  </div>
<% end %>
Fragment Caching

<% cache :lang => request.language do %>
  <div class="person">
    <div class="image">
      <%= img_tag image_url(cast.person.image) %>
    </div>
    <strong>
      <%= link_to cast.person.name,
                  person_url(cast.person) %>
    </strong>
  </div>
<% end %>
Fragment Caching


ActionController::Base.fragment_cache_store =
                     :mem_cache_store, "localhost"
Fragment Caching


ActionController::Base.fragment_cache_store =
              OMDB::Cache::FragmentCache.instance
Fragment Caching


ActionController::Base.fragment_cache_store =
              OMDB::Cache::FragmentCache.instance


# Setting the default MemCache server
OMDB::Cache::MemCacheStore.servers = 'localhost'
Fragment Caching

   cached content




      MemCache
Fragment Caching

           cached content




MemCache      MemCache      MemCache


  :fr           :de           :en
Fragment Caching

            cached content




Namespace      Namespace     Namespace


  :fr            :de           :en
Fragment Caching

http://www.omdb.org/movies/2062.html.fr




    MemCache   MemCache    MemCache


      :fr        :de         :en
Fragment Caching

http://www.omdb.org/movies/2062.html.de




    MemCache   MemCache    MemCache


      :fr        :de         :en
Fragment Caching

http://www.omdb.org/movies/2062.html.en




    MemCache   MemCache    MemCache


      :fr        :de         :en
Fragment Caching

# Delete the fragment for one language
expire_fragment :controller => 'movies',
                :action     => 'show',
                :id         => 2062,
                :lang       => :en


# delete the fragment for all languages
expire_fragment :controller => 'movies',
                :action     => 'show',
                :id         => 2062,
Tests
how to test the views
Test Page Caching

def test_caching_show
  accept :xml
  # language is a custom extension
  language :de

  page = "/casts/#{casts(:first).id}.xml.de"
  assert_cached_page( page ) do
    get :show, :id => casts(:first).id
    assert_response :success
  end
end
Test Page Caching

def test_expire_show
  accept :xml
  language :de

  page = "/casts/#{casts(:first).id}.xml.de"
  assert_no_cached_page( page ) do
    put :update, :id => casts(:first).id,
                 :job => Job.composer.id
    assert_response :success
  end
end
Test Fragment Caching
def test_expire_fragment
  accept :js
  language :en
  params = { :controller => 'casts',
             :id         => casts(:first).id,
             :template   => 'cast' }

  assert_cached_fragment( params ) do
    put :update, :id => casts(:first).id,
                 :job => Job.composer.id
    assert_template 'cast'
  end

  assert_no_cached_fragment( params ) do
    casts(:first).save
  end
end
Where to get the plugins
The plugins are available from

http://svn.omdb-beta.org/plugins/mlr
http://svn.omdb-beta.org/plugins/mlcache

There will be an official announcement on

http://blog.omdb-beta.org/
thank you

Más contenido relacionado

La actualidad más candente

Gradle + Google I/O 2014 remarks
Gradle + Google I/O 2014 remarksGradle + Google I/O 2014 remarks
Gradle + Google I/O 2014 remarksDamian Mee
 
One Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST InterfaceOne Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST Interfaceabrummett
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Prxibbar
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf Conference
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Alberto Perdomo
 
PHP language presentation
PHP language presentationPHP language presentation
PHP language presentationAnnujj Agrawaal
 
SADI for GMOD: Semantic Web Services for Model Organism Databases
SADI for GMOD: Semantic Web Services for Model Organism DatabasesSADI for GMOD: Semantic Web Services for Model Organism Databases
SADI for GMOD: Semantic Web Services for Model Organism Databasesbenvvalk
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortegaarman o
 
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con Symfony
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con SymfonyPHPCR e API Platform: cosa significa davvero sviluppare un CMF con Symfony
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con SymfonyInnoteam Srl
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in PerlNaveen Gupta
 
PyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slidesPyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slidesArtur Barseghyan
 
Getting started with Django 1.8
Getting started with Django 1.8Getting started with Django 1.8
Getting started with Django 1.8rajkumar2011
 
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)ZFConf Conference
 
Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Nafis Ahmed
 

La actualidad más candente (20)

Gradle + Google I/O 2014 remarks
Gradle + Google I/O 2014 remarksGradle + Google I/O 2014 remarks
Gradle + Google I/O 2014 remarks
 
One Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST InterfaceOne Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST Interface
 
Rest
RestRest
Rest
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Pr
 
Php Presentation
Php PresentationPhp Presentation
Php Presentation
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
 
Ci2
Ci2Ci2
Ci2
 
PHP language presentation
PHP language presentationPHP language presentation
PHP language presentation
 
SADI for GMOD: Semantic Web Services for Model Organism Databases
SADI for GMOD: Semantic Web Services for Model Organism DatabasesSADI for GMOD: Semantic Web Services for Model Organism Databases
SADI for GMOD: Semantic Web Services for Model Organism Databases
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortega
 
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con Symfony
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con SymfonyPHPCR e API Platform: cosa significa davvero sviluppare un CMF con Symfony
PHPCR e API Platform: cosa significa davvero sviluppare un CMF con Symfony
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in Perl
 
PyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slidesPyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slides
 
Api Design
Api DesignApi Design
Api Design
 
You suck at Memory Analysis
You suck at Memory AnalysisYou suck at Memory Analysis
You suck at Memory Analysis
 
Getting started with Django 1.8
Getting started with Django 1.8Getting started with Django 1.8
Getting started with Django 1.8
 
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)
ZFConf 2012: Dependency Management в PHP и Zend Framework 2 (Кирилл Чебунин)
 
ZendCon 08 php 5.3
ZendCon 08 php 5.3ZendCon 08 php 5.3
ZendCon 08 php 5.3
 
Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1
 

Destacado

12.01.13 Quiz prelims answers
12.01.13 Quiz prelims answers 12.01.13 Quiz prelims answers
12.01.13 Quiz prelims answers Aditya Jayaprakash
 
Brazil tourist visa
Brazil tourist visaBrazil tourist visa
Brazil tourist visaaishnme
 
Patrocinadors
PatrocinadorsPatrocinadors
Patrocinadorsabonill2
 
Colonies '09 cicle mitjà
Colonies '09 cicle mitjàColonies '09 cicle mitjà
Colonies '09 cicle mitjàabonill2
 

Destacado (8)

12.01.13 Quiz prelims answers
12.01.13 Quiz prelims answers 12.01.13 Quiz prelims answers
12.01.13 Quiz prelims answers
 
2012 President's Cup Charity Golf Classic
2012 President's Cup Charity Golf Classic2012 President's Cup Charity Golf Classic
2012 President's Cup Charity Golf Classic
 
Brazil tourist visa
Brazil tourist visaBrazil tourist visa
Brazil tourist visa
 
Patrocinadors
PatrocinadorsPatrocinadors
Patrocinadors
 
15 march 2017 chatra ekta
15 march   2017 chatra ekta15 march   2017 chatra ekta
15 march 2017 chatra ekta
 
Ecollibre
EcollibreEcollibre
Ecollibre
 
Colonies '09 cicle mitjà
Colonies '09 cicle mitjàColonies '09 cicle mitjà
Colonies '09 cicle mitjà
 
Couchdb Nosql
Couchdb NosqlCouchdb Nosql
Couchdb Nosql
 

Similar a Caching in a multilanguage environment

Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!cloudbring
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
sMash at May NYPHP UG
sMash at May NYPHP UGsMash at May NYPHP UG
sMash at May NYPHP UGProject Zero
 
Zend Amf And Flex
Zend Amf And FlexZend Amf And Flex
Zend Amf And Flexriafox
 
HTML5 Accessibility CSUN 2012
HTML5 Accessibility CSUN 2012HTML5 Accessibility CSUN 2012
HTML5 Accessibility CSUN 2012Steven Faulkner
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails DevsDiacode
 
Tuning web performance
Tuning web performanceTuning web performance
Tuning web performanceGeorge Ang
 
Tuning Web Performance
Tuning Web PerformanceTuning Web Performance
Tuning Web PerformanceEric ShangKuan
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
Rails 2.0 Presentation
Rails 2.0 PresentationRails 2.0 Presentation
Rails 2.0 PresentationScott Chacon
 
The Render API in Drupal 7
The Render API in Drupal 7The Render API in Drupal 7
The Render API in Drupal 7frandoh
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular applicationmirrec
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Deploy Rails Application by Capistrano
Deploy Rails Application by CapistranoDeploy Rails Application by Capistrano
Deploy Rails Application by CapistranoTasawr Interactive
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsMarcelo Pinheiro
 

Similar a Caching in a multilanguage environment (20)

Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!
 
HTML5와 모바일
HTML5와 모바일HTML5와 모바일
HTML5와 모바일
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
sMash at May NYPHP UG
sMash at May NYPHP UGsMash at May NYPHP UG
sMash at May NYPHP UG
 
Zend Amf And Flex
Zend Amf And FlexZend Amf And Flex
Zend Amf And Flex
 
HTML5 Accessibility CSUN 2012
HTML5 Accessibility CSUN 2012HTML5 Accessibility CSUN 2012
HTML5 Accessibility CSUN 2012
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
Tuning web performance
Tuning web performanceTuning web performance
Tuning web performance
 
Tuning Web Performance
Tuning Web PerformanceTuning Web Performance
Tuning Web Performance
 
Sprockets
SprocketsSprockets
Sprockets
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
 
Rails 2.0 Presentation
Rails 2.0 PresentationRails 2.0 Presentation
Rails 2.0 Presentation
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
The Render API in Drupal 7
The Render API in Drupal 7The Render API in Drupal 7
The Render API in Drupal 7
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Deploy Rails Application by Capistrano
Deploy Rails Application by CapistranoDeploy Rails Application by Capistrano
Deploy Rails Application by Capistrano
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability Systems
 

Más de elliando dias

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slideselliando dias
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScriptelliando dias
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structureselliando dias
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de containerelliando dias
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agilityelliando dias
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Librarieselliando dias
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!elliando dias
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Webelliando dias
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduinoelliando dias
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorceryelliando dias
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Designelliando dias
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makeselliando dias
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.elliando dias
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebookelliando dias
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Studyelliando dias
 

Más de elliando dias (20)

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slides
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScript
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structures
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de container
 
Geometria Projetiva
Geometria ProjetivaGeometria Projetiva
Geometria Projetiva
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!
 
Ragel talk
Ragel talkRagel talk
Ragel talk
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Web
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduino
 
Minicurso arduino
Minicurso arduinoMinicurso arduino
Minicurso arduino
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorcery
 
Rango
RangoRango
Rango
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Design
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makes
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebook
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Study
 

Último

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Último (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Caching in a multilanguage environment

  • 1. Caching in a multi- language environment Benjamin Krause <benjamin@omdb.org>
  • 3. Caching in Rails ‣ Page Caching ‣ Action Caching ‣ Fragment Caching
  • 4. Caching in Rails ‣ Page Caching ‣ ______________ Action Caching ‣ Fragment Caching
  • 5. Caching in Rails Page Caching Fragment Caching routing routing routing before filters before filters before filters controller controller controller CACHED rendering rendering parts CACHED after filters after filters after filters illustration by Tammo Freese
  • 6. Page Caching Webserver File.exists? !File.exists? __ _ ____ ___ ___ _ _ __ ____ __ ___ __ Mongrel __ _ ____
  • 8. Caching in Rails ‣ No support for caching in different languages ‣ No support to expire all language- caches at once ‣ No support for language-negotiation
  • 9. Content Negotiation let the user decide, what he wants to see
  • 10. Content Negotiation consists of format negotiation and language negotiation
  • 12. Format Negotiation > HTTP “Accept” Header Accept: text/xml,application/xml, application/xhtml+xml,text/html > Rails supports format negotiation > Rails allows you to request a format explicitly (extra routes)
  • 13. Format Negotiation http://www.omdb.org/movies/2062.html <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Ratatouille</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> http://www.omdb.org/movies/2062.xml <?xml version="1.0" encoding="UTF-8"?> <movie> <name>Ratatouille</name> <abstract> Remy is a rat, with a talent and passion for cooking. He dreams of one day working in a real restaurant
  • 14. Format Negotiation class MoviesController < ApplicationController def show respond_to do |format| format.html { render } format.xml { render :xml => @movie.to_xml } format.js { render :json => @movie.to_json } end end end
  • 15. Language Negotiation > HTTP “Accept-Language” Header Accept-Language: en-us,en;q=0.7,de;q=0.3 > Rails ignores the HTTP Header > Rails doesn’t add language routes
  • 17. Language Negotiation http://www.omdb.org/movies/2062.html.en Routing Error no route found to match "/movies/2062.html.en" with {:method=>:get} http://www.omdb.org/movies/2062.xml.de Routing Error no route found to match "/movies/2062.xml.de" with {:method=>:get}
  • 18. let’s fix that extending Rails
  • 19. Language Routes extending Rails to set language routes
  • 20. Language Routes # Adding default routes for # GET /movies/<id> # GET /movies/<id>.<format> # PUT /movies/<id> # PUT /movies/<id>.<format> # ... map.resources :movies map.resources :people map.resources :casts
  • 21. Language Routes There are several possible routes, how to add a language parameter. http://www.omdb.org/movies/2062.html?lang=de http://de.omdb.org/movies/2062.html http://www.omdb.org/de/movies/2062.html http://www.omdb.org/movies/2062.de.html http://www.omdb.org/movies/2062.html.de
  • 22. Language Routes There are several possible routes, how to add a language parameter. http://www.omdb.org/movies/2062.html?lang=de http://de.omdb.org/movies/2062.html http://www.omdb.org/de/movies/2062.html http://www.omdb.org/movies/2062.de.html http://www.omdb.org/movies/2062.html.de
  • 23. Language Routes # Taken from Rails 1.2.3 # /actionpack-1.13.3/lib/action_controller/resources.rb # with slight modifications to fit this slide :-) action_options = action_options_for("show", resource) map.named_route( "#{resource.name_prefix}#{resource.singular}", resource.member_path, action_options ) map.named_route( "f_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", action_options )
  • 24. Language Routes # Taken from Rails 1.2.3 # /actionpack-1.13.3/lib/action_controller/resources.rb # with slight modifications to fit this slide :-) action_options = action_options_for("show", resource) { :conditions => { :method => :get }, :requirements => { :id map.named_route( => /[^/;.,?]+/ }, :action => "show" } "#{resource.name_prefix}#{resource.singular}", resource.member_path, action_options ) map.named_route( "f_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", action_options )
  • 25. Language Routes # Taken from Rails 1.2.3 # /actionpack-1.13.3/lib/action_controller/resources.rb # with slight modifications to fit this slide :-) action_options = action_options_for("show", resource) { :conditions => { :method => :get }, :requirements => { :id map.named_route( => /[^/;.,?]+/ }, :action => "show" } "#{resource.name_prefix}#{resource.singular}", resource.member_path, action_options ) map.named_route( "f_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", action_options ) /movies/:id
  • 26. Language Routes # Extending # ActionController::Resources::map_new_actions # ActionController::Resources::map_member_actions # and others to support a language parameter map.named_route( "fl_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format.:lang", action_options )
  • 27. Language Routes # Extending # ActionController::Resources::map_new_actions # ActionController::Resources::map_member_actions # and others to support a language parameter map.named_route( "fl_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format.:lang", action_options ) { :conditions => { :method => :get }, :requirements => { :id => /[^/;.,?]+/ :lang => /^fr|de|en$/ }, :action => "show" }
  • 28. Language Routes http://www.omdb.org/movies/2062.html.en <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Ratatouille</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> http://www.omdb.org/movies/2062.xml.de <?xml version="1.0" encoding="UTF-8"?> <movie> <name>Ratatouille</name> <abstract> Remy is a rat, with a talent and passion for cooking. He dreams of one day working in a real restaurant
  • 29. Accept-Language extending Rails to know about the requested language
  • 30. Accept-Language # in environment.rb # # These are custom extensions, this is not part # of Rails AC = ActionController AC::AbstractRequest.default_language = :en AC::AbstractRequest.acceptable_languages = :fr, :de, :en
  • 31. Accept-Language # Taken from Rails 1.2.3 # /actionpack-1.13.3/lib/action_controller/request.rb # Returns the accepted MIME type for the request def accepts @accepts ||= if @env['HTTP_ACCEPT'].to_s.strip.empty? [ content_type, Mime::ALL ] else Mime::Type.parse(@env['HTTP_ACCEPT']) end end
  • 32. Accept-Language class ActionController::AbstractRequest def accepts_languages begin @accepts_languages ||= @env['HTTP_ACCEPT_LANGUAGE'].split(",").collect {|l| l.gsub(/;.*$/, '').gsub(/-.*$/,'').downcase.to_sym }.push(default_language).uniq @accepts_languages.delete_if { |l| !acceptable_languages.include?(l) } rescue NoMethodError @accepts_languages = default_language.is_a?(Array) ? default_language : [ default_language ] end end end
  • 33. Accept-Language Accept-Language: fr => [ :fr, :en ] Accept-Language: fr; q=1.0, en; q=0.5, fi; q=0.2 => [ :fr, :en ] Accept-Language: en-us,en;q=0.7,de;q=0.3 => [ :en, :de ] Accept-Language: fi, es => [ :en ]
  • 34. Accept-Language class ActionController::AbstractRequest def language params[:lang] || accepts_languages.first end end class ApplicationController before_filter :set_language def set_language @language = session[:lang] || request.language # for Globalize: # @language = Locale.set(@language) # for Gettext: # params[:lang] = @language unless params[:lang] end end
  • 35. Language Routes http://www.omdb.org/movies/2062.html.en <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Ratatouille</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> http://www.omdb.org/movies/2062.xml.de <?xml version="1.0" encoding="UTF-8"?> <movie> <name>Ratatouille</name> <abstract> Eine Gourmet-Ratte muss so einiges erleiden, um ihre Lust auf exquisite Speisen befriedigen zu können.
  • 37. Page Caching extending Rails to support language-based page caching
  • 38. Page Caching Webserver File.exists? !File.exists? __ _ ____ ___ ___ _ _ __ ____ __ ___ __ Mongrel __ _ ____
  • 39. Page Caching class MoviesController < ApplicationController caches_page :show def show respond_to |format| do format.html { render } format.xml { render :xml => @movie.to_xml } format.js { render :json => @movie.to_json } end end end
  • 40. Page Caching GET /movies/2062 Mongrel caches_page ~/public/movies/2062.html
  • 41. Page Caching # Taken from Rails 1.2.3 # /actionpack-1.13.3/lib/action_controller/caching.rb def cache_page(content = nil, options = {}) return unless perform_caching && caching_allowed self.class.cache_page(content || response.body, url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))) end
  • 42. Page Caching # Reimplementing the cache_page method module ActionController::Caching::Pages def cache_page(content = nil, options = {}) return unless perform_caching && caching_allowed self.class.cache_page(content || response.body, url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format], :lang => request.language))) end end
  • 43. Page Caching GET /movies/2062 Mongrel caches_page ~/public/movies/2062.html.en
  • 44. Page Caching curl http://www.omdb.org/movies/2062 -H 'Accept: application/xml' => ~/public/movies/2062.xml.en
  • 45. Page Caching curl http://www.omdb.org/movies/2062 -H 'Accept-Language: fr, en, de' => ~/public/movies/2062.html.fr
  • 46. Page Caching curl http://www.omdb.org/movies/2062 -H 'Accept-Language: fr, en, de' -H 'Accept: application/xml' => ~/public/movies/2062.xml.fr
  • 47. Apache how-to use Apaches content negotiations
  • 48. Apache # Taken from # http://mongrel.rubyforge.org/docs/apache.html # Rewrite to check for Rails cached page RewriteRule ^([^.]+)$ $1.html [QSA] # Redirect all non-static requests to cluster RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]
  • 49. Apache # Taken from # http://bugs.omdb.org/browser/trunk/conf/webserver/apache.conf # Perform content-negotiation and send to mongrel # if not cached. RewriteCond %{DOCUMENT_ROOT}/%{LA-U:REQUEST_URI} !-f RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]
  • 50. Apache Apache 2.2 mod_rewrite documentation: %{LA-U:variable} can be used for look-aheads which perform an internal (URL-based) sub-request to determine the final value of variable.
  • 51. Apache # Prefer text/html over other Accept Headers # Simplified RewriteConditions RewriteCond %{HTTP_ACCEPT} text/html RewriteCond %{SCRIPT_FILENAME} !.html$ RewriteCond %{IS_SUBREQ} 'false' RewriteRule ^/(.*)$ /%{SCRIPT_FILENAME}.html [QSA] # Perform content-negotiation and send to mongrel # if not cached. RewriteCond %{DOCUMENT_ROOT}/%{LA-U:REQUEST_URI} !-f RewriteCond %{IS_SUBREQ} 'false' RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]
  • 52. GET /movies/2062 Apache Subrequest Apache /movies/2062.html.en Content Negotiation File.exists? !File.exists? __ ___ __ _ __ __ __ __ ___ __ __ _ _ __ ___ __ Mongrel ___ __ _ _ _ __ __ _ _ __
  • 53. Apache # Let the user change the language in your # application SetEnvIf Cookie "language=(..)" prefer-language=$1
  • 54. Fragment Caching extending Rails to support language-based fragment caching
  • 55. Fragment Caching <% cache do %> <div class="person"> <div class="image"> <%= img_tag image_url(cast.person.image) %> </div> <strong> <%= link_to cast.person.name, person_url(cast.person) %> </strong> </div> <% end %>
  • 56. Fragment Caching cached content MemCache
  • 57. Fragment Caching <% cache :lang => request.language do %> <div class="person"> <div class="image"> <%= img_tag image_url(cast.person.image) %> </div> <strong> <%= link_to cast.person.name, person_url(cast.person) %> </strong> </div> <% end %>
  • 58. Fragment Caching <% cache :lang => request.language do %> <div class="person"> <div class="image"> <%= img_tag image_url(cast.person.image) %> </div> <strong> <%= link_to cast.person.name, person_url(cast.person) %> </strong> </div> <% end %>
  • 61. Fragment Caching ActionController::Base.fragment_cache_store = OMDB::Cache::FragmentCache.instance # Setting the default MemCache server OMDB::Cache::MemCacheStore.servers = 'localhost'
  • 62. Fragment Caching cached content MemCache
  • 63. Fragment Caching cached content MemCache MemCache MemCache :fr :de :en
  • 64. Fragment Caching cached content Namespace Namespace Namespace :fr :de :en
  • 65. Fragment Caching http://www.omdb.org/movies/2062.html.fr MemCache MemCache MemCache :fr :de :en
  • 66. Fragment Caching http://www.omdb.org/movies/2062.html.de MemCache MemCache MemCache :fr :de :en
  • 67. Fragment Caching http://www.omdb.org/movies/2062.html.en MemCache MemCache MemCache :fr :de :en
  • 68. Fragment Caching # Delete the fragment for one language expire_fragment :controller => 'movies', :action => 'show', :id => 2062, :lang => :en # delete the fragment for all languages expire_fragment :controller => 'movies', :action => 'show', :id => 2062,
  • 69. Tests how to test the views
  • 70. Test Page Caching def test_caching_show accept :xml # language is a custom extension language :de page = "/casts/#{casts(:first).id}.xml.de" assert_cached_page( page ) do get :show, :id => casts(:first).id assert_response :success end end
  • 71. Test Page Caching def test_expire_show accept :xml language :de page = "/casts/#{casts(:first).id}.xml.de" assert_no_cached_page( page ) do put :update, :id => casts(:first).id, :job => Job.composer.id assert_response :success end end
  • 72. Test Fragment Caching def test_expire_fragment accept :js language :en params = { :controller => 'casts', :id => casts(:first).id, :template => 'cast' } assert_cached_fragment( params ) do put :update, :id => casts(:first).id, :job => Job.composer.id assert_template 'cast' end assert_no_cached_fragment( params ) do casts(:first).save end end
  • 73. Where to get the plugins The plugins are available from http://svn.omdb-beta.org/plugins/mlr http://svn.omdb-beta.org/plugins/mlcache There will be an official announcement on http://blog.omdb-beta.org/