g3d / espresso.github.com Goto Github PK
View Code? Open in Web Editor NEWOfficial Website
Official Website
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Espresso Framework</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="javascripts/jquery.js" type="text/javascript"></script> <link href="javascripts/bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <link href="javascripts/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" /> <script src="javascripts/bootstrap/js/bootstrap.min.js" type="text/javascript"></script> <link href="javascripts/google-code-prettify/prettify.css" type="text/css" rel="stylesheet" /> <script src="javascripts/google-code-prettify/prettify.js" type="text/javascript"></script> <link href="stylesheets/master.css" type="text/css" rel="stylesheet" /> </head> <body> <div class="container"> <div class="row"> <div class="span2"> <a href="index.html"> <img src="images/logo.png" class="pull-right logo" /></a> </div> <div class="span6"> <h1> <a href="index.html"> Espresso Framework</a> </h1> <h4> Scalable Web Framework aimed at Speed and Simplicity </h4> </div> <div class="span pull-right"> <div class="row"> <div class="span"> <h4> <a href="presentation.html"> Official Presentation</a> </h4> </div> <div class="span"> <a href="presentation.html"> <img src="icons/elementary/64/Apps-background-icon.png" /></a> </div> </div> </div> </div> <hr/> <div class="row" style="text-align: center;"> <div class="btn-toolbar"> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Intro.html" class="btn"> Intro</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Intro.html#actions"> Actions</a> </li> <li> <a href="Intro.html#controllers"> Controllers</a> </li> <li> <a href="Intro.html#slices"> Slices</a> </li> <li> <a href="Intro.html#mvc-"> MVC?</a> </li> <li> <a href="Intro.html#models-"> Models?</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Routing.html" class="btn"> Routing</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Routing.html#base-url"> Base URL</a> </li> <li> <a href="Routing.html#canonicals"> Canonicals</a> </li> <li> <a href="Routing.html#actions"> Actions</a> </li> <li> <a href="Routing.html#actions-mapping"> Actions Mapping</a> </li> <li> <a href="Routing.html#parametrization"> Parametrization</a> </li> <li> <a href="Routing.html#format"> Format</a> </li> <li> <a href="Routing.html#restful-actions"> RESTful Actions</a> </li> <li> <a href="Routing.html#aliases"> Aliases</a> </li> <li> <a href="Routing.html#rewriter"> Rewriter</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Setup.html" class="btn"> Setup</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Setup.html#global-setup"> Global Setup</a> </li> <li> <a href="Setup.html#setup-by-name"> Setup by Name</a> </li> <li> <a href="Setup.html#setup-by-format"> Setup by Format</a> </li> <li> <a href="Setup.html#remote-setup"> Remote Setup</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Workflow.html" class="btn"> Workflow</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Workflow.html#route"> Route</a> </li> <li> <a href="Workflow.html#params"> Params</a> </li> <li> <a href="Workflow.html#passing-control"> Passing Control</a> </li> <li> <a href="Workflow.html#fetching-body"> Fetching Body</a> </li> <li> <a href="Workflow.html#halt"> Halt</a> </li> <li> <a href="Workflow.html#redirect"> Redirect</a> </li> <li> <a href="Workflow.html#reload"> Reload</a> </li> <li> <a href="Workflow.html#error-handlers"> Error Handlers</a> </li> <li> <a href="Workflow.html#hooks"> Hooks</a> </li> <li> <a href="Workflow.html#authorization"> Authorization</a> </li> <li> <a href="Workflow.html#sessions"> Sessions</a> </li> <li> <a href="Workflow.html#flash"> Flash</a> </li> <li> <a href="Workflow.html#cookies"> Cookies</a> </li> <li> <a href="Workflow.html#content-type"> Content Type</a> </li> <li> <a href="Workflow.html#charset"> Charset</a> </li> <li> <a href="Workflow.html#cache-control"> Cache Control</a> </li> <li> <a href="Workflow.html#expires"> Expires</a> </li> <li> <a href="Workflow.html#last-modified"> Last Modified</a> </li> <li> <a href="Workflow.html#accepted-content-type"> Accepted Content Type</a> </li> <li> <a href="Workflow.html#cache-manager"> Cache Manager</a> </li> <li> <a href="Workflow.html#send-file"> Send File</a> </li> <li> <a href="Workflow.html#send-files"> Send Files</a> </li> <li> <a href="Workflow.html#attachment"> Attachment</a> </li> <li> <a href="Workflow.html#headers"> Headers</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="ViewAPI.html" class="btn"> View API</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="ViewAPI.html#engine"> Engine</a> </li> <li> <a href="ViewAPI.html#extension"> Extension</a> </li> <li> <a href="ViewAPI.html#templates-path"> Templates Path</a> </li> <li> <a href="ViewAPI.html#layouts-path"> Layouts Path</a> </li> <li> <a href="ViewAPI.html#layout"> Layout</a> </li> <li> <a href="ViewAPI.html#rendering-templates"> Rendering Templates</a> </li> <li> <a href="ViewAPI.html#rendering-layouts"> Rendering Layouts</a> </li> <li> <a href="ViewAPI.html#ad-hoc-rendering"> Ad hoc Rendering</a> </li> <li> <a href="ViewAPI.html#path-resolver"> Path Resolver</a> </li> <li> <a href="ViewAPI.html#templates-compilation"> Templates Compilation</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Streaming.html" class="btn"> Streaming</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Streaming.html#server-sent-events"> Server-Sent Events</a> </li> <li> <a href="Streaming.html#websockets"> WebSockets</a> </li> <li> <a href="Streaming.html#chunked-responses"> Chunked Responses</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Assets.html" class="btn"> Assets</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Assets.html#intro"> Intro</a> </li> <li> <a href="Assets.html#mapper"> Mapper</a> </li> <li> <a href="Assets.html#server"> Server</a> </li> <li> <a href="Assets.html#helpers"> Helpers</a> </li> <li> <a href="Assets.html#loader"> Loader</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="CRUD.html" class="btn"> CRUD</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="CRUD.html#intro"> Intro</a> </li> <li> <a href="CRUD.html#resource"> Resource</a> </li> <li> <a href="CRUD.html#excluded-params"> Excluded Params</a> </li> <li> <a href="CRUD.html#root"> Root</a> </li> <li> <a href="CRUD.html#response"> Response</a> </li> <li> <a href="CRUD.html#error-handler"> Error Handler</a> </li> <li> <a href="CRUD.html#access-restriction"> Access Restriction</a> </li> </ul> </div> <div class="btn-group" style="text-align: left; margin: 5px;"> <a href="Deploy.html" class="btn"> Deploy</a> <button class="btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </button> <ul class="dropdown-menu"> <li> <a href="Deploy.html#controllers"> Controllers</a> </li> <li> <a href="Deploy.html#slices"> Slices</a> </li> <li> <a href="Deploy.html#roots"> Roots</a> </li> <li> <a href="Deploy.html#run"> Run</a> </li> <li> <a href="Deploy.html#config-ru"> config.ru</a> </li> </ul> </div> </div> </div> <hr/> <p><a href="http://espresso.github.com/"> <img src="http://espresso.github.com/images/logo.png" align="right" /></a></p> <h1><a href="http://espresso.github.com">Espresso</a></h1> <p><strong>Scalable Web Framework aimed at Speed and Simplicity</strong></p> <p> <a href="https://travis-ci.org/espresso/espresso"> <img src="https://travis-ci.org/espresso/espresso.png"></a> </p> <h2 id='quick-start'><a href='#quick-start'>Quick Start</a></h2> <p><strong>Ready</strong></p> <pre> $ [sudo] gem install e </pre> <p><strong>Set</strong></p> <pre> require 'e' class App < E map '/' def index # ... end end </pre> <p><strong>Go!</strong></p> <pre> App.run </pre> <h3 id='espresso-in-the-wild-'><a href='#espresso-in-the-wild-'>Espresso in the wild?</a></h3> <p><a href="http://cibox.org">CIBox</a> service are entirely built on Espresso Framework.</p> <hr/> <h1 id='tutorial'><a href='#tutorial'>Tutorial</a></h1> <h3 id='intro'><a href='#intro'>Intro</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Intro.md#actions">Actions</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Intro.md#controllers">Controllers</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Intro.md#slices">Slices</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Intro.md#mvc">MVC?</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Intro.md#models">Models?</a></p> <h3 id='routing'><a href='#routing'>Routing</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#base-url">Base URL</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#canonicals">Canonicals</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#actions">Actions</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#actions-mapping">Actions Mapping</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#parametrization">Parametrization</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#format">Format</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#restful-actions">RESTful Actions</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#aliases">Aliases</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Routing.md#rewriter">Rewriter</a></p> <h3 id='setup'><a href='#setup'>Setup</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Setup.md#global-setup">Global Setup</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Setup.md#setup-by-name">Setup by Name</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Setup.md#setup-by-format">Setup by Format</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Setup.md#remote-setup">Remote Setup</a></p> <h3 id='workflow'><a href='#workflow'>Workflow</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#route">Route</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#params">Params</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#passing-control">Passing Control</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#fetching-body">Fetching Body</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#halt">Halt</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#redirect">Redirect</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#reload">Reload</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#error-handlers">Error Handlers</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#hooks">Hooks</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#authorization">Authorization</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#sessions">Sessions</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#flash">Flash</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#cookies">Cookies</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#content-type">Content Type</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#charset">Charset</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#cache-control">Cache Control</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#expires">Expires</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#last-modified">Last Modified</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#accepted-content-type">Accepted Content Type</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#cache-manager">Cache Manager</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#send-file">Send File</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#send-files">Send Files</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#attachment">Attachment</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#headers">Headers</a></p> <h3 id='view-api'><a href='#view-api'>View API</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#engine">Engine</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#extension">Extension</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#templates-path">Templates Path</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#layouts-path">Layouts Path</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#layout">Layout</a> |</p> <br> <p><a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#rendering-templates">Rendering Templates</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#rendering-layouts">Rendering Layouts</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#ad-hoc-rendering">Ad hoc Rendering</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#path-resolver">Path Resolver</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#templates-compilation">Templates Compilation</a></p> <h3 id='streaming'><a href='#streaming'>Streaming</a></h3> <p>Note: Streaming in Espresso is working only with <a href="https://github.com/celluloid/reel">Reel</a> web server of version 0.3 and up</p> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Streaming.md#server-sent-events">Server-Sent Events</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Streaming.md#websockets">WebSockets</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Streaming.md#chunked-responses">Chunked Responses</a></p> <h3 id='assets'><a href='#assets'>Assets</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Assets.md#intro">Intro</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Assets.md#mapper">Mapper</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Assets.md#server">Server</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Assets.md#helpers">Helpers</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Assets.md#loader">Loader</a></p> <h3 id='crud'><a href='#crud'>CRUD</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#intro">Intro</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#resource">Resource</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#excluded-params">Excluded Params</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#root">Root</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#response">Response</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#error-handler">Error Handler</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/CRUD.md#access-restriction">Access Restriction</a></p> <h3 id='deploy'><a href='#deploy'>Deploy</a></h3> <p><a href="https://github.com/espresso/espresso/blob/master/docs/Deploy.md#controllers">Controllers</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Deploy.md#slices">Slices</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Deploy.md#roots">Roots</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Deploy.md#run">Run</a> | <a href="https://github.com/espresso/espresso/blob/master/docs/Deploy.md#configru">config.ru</a></p> <hr/> <h1 id='highlights---motivation'><a href='#highlights---motivation'>Highlights / Motivation</a></h1> <h2 id='performance'><a href='#performance'>Performance</a></h2> <p>In terms of performance, the only really important thing for any framework it is to add as low overhead as possible.</p> <p>The overhead are the time consumed by framework to accept the request then prepare and send response.</p> <p>The tests that follows will allow to disclose the overhead added by various frameworks.</p> <p>The overhead are calculated by dividing 1000 milliseconds to <strong>framework’s standard speed</strong>.</p> <p>The <strong>framework’s standard speed</strong> are the speed of HelloWorld app running on top of given framework.</p> <p>The <strong>framework’s standard speed</strong> means nothing by itself. It is only used to calculate the framework’s overhead.</p> <p>Tested apps will run on Thin web server and will return a trivial "Hello World!" response.</p> <p>Hardware used:</p> <pre><code>Processor Name: Intel Core i5 Processor Speed: 3.31 GHz Number of Processors: 1 Total Number of Cores: 4 Memory: 8 GB </code></pre> <p>To run tests on your hardware, clone Espresso Framework repository and execute <code>rake overhead</code> inside it.</p> <p>Test results:</p> <pre><code>--- Speed Overhead 1ms-app 5ms-app 10ms-app 20ms-app 50ms-app 100ms-app espresso 5518 0.18ms 847 193 98 49 19 9 sinatra 3629 0.28ms 783 189 97 49 19 9 rails 792 1.26ms 442 159 88 47 19 9 --- </code></pre> <p><strong>1ms-app</strong> shows your app speed when your actions takes <strong>1ms</strong> to run.<br> <strong>10ms-app</strong> shows your app speed when your actions takes <strong>10ms</strong> to run.<br> etc.</p> <p>The app speed are calculated as follow:</p> <pre><code>1000 / (time taken by action + time taken by framework) </code></pre> <p>So, if your actions takes about 1ms and you use a framework with overhead of 0.18ms, the app speed will be:</p> <pre><code>1000 / ( 1 + 0.18 ) = 847 requests per second </code></pre> <p>However, if framework's overhead is of <strong>1ms</strong> or more, the app speed will decrease dramatically:</p> <pre><code>1000 / ( 1 + 1.26 ) = 442 requests per second </code></pre> <p><strong>Conclusions?</strong></p> <p>The framework speed matter only if your code matter.</p> <p>If you develop a site aimed to serve a serious amount of requests, you should write actions that takes insignificant amount of time.</p> <p>Only after that it make sense to think about framework speed.</p> <p><strong>Worth to Note</strong> - Espresso has built-in <a href="https://github.com/espresso/espresso/blob/master/docs/Workflow.md#cache-manager">cache manager</a> as well as <a href="https://github.com/espresso/espresso/blob/master/docs/ViewAPI.md#templates-compilation">views compiler</a>.</p> <p>These tools may help you to dramatically reduce the time consumed by your actions.</p> <h2 id='natural-action-routes-params'><a href='#natural-action-routes-params'>Natural Action/Routes/Params</a></h2> <p>I never understood why should i create actions in some file, then open another file and directing requests to created action.<br> Even worse! To use params inside action, i have to remember how i named them in another file. And when i want to change a param name i have to change it in both files?</p> <p>What about consistency?<br></p> <p>A good tradeoff would be to use some DSL.</p> <pre> get '/book/:id' do params[:id] end </pre> <p>Looks much better.</p> <p>But! Strings/Regexps as action names? No, thanks.</p> <p>What if i need to remount a bunch of actions to a new root? Say from /news to /headlines? Refactoring? Using vars/constants in names? No, Thanks.</p> <p>How do i setup multiple actions?<br> How do i find out the currently running action?</p> <p>What if i do a request like "/book/100/?id=200"? What? Should i use unique param names? No, thanks.</p> <p>etc. etc.</p> <p>And why should i remember so many non-natural stuff?</p> <p>Is not Ruby powerfull enough? I guess it is:</p> <pre> def book id end </pre> <p>That's a regular <strong>Ruby method</strong> and a regular <strong>Espresso action</strong>.<br> That's also an Espresso route. Yes, the app will respond to "/book/100"<br> And of course action params are used naturally, through method arguments(<code>id</code> rather than <code>params[:id]</code>).</p> <p>And all this offered by Ruby for free! Why to reinvent the wheel?</p> <h2 id='expressive-setup'><a href='#expressive-setup'>Expressive Setup</a></h2> <p>Usually you do not want to instruct each action about how it should behave.</p> <p>It would take eras to define inside each action what content type should it return or what layout should it render.</p> <p>Instead, you will use few lines of code at class level to write instructions that will be followed by all actions.</p> <p><strong>Example:</strong> Instruct <strong>all</strong> actions under <code>App</code> controller to return JSON Content-Type</p> <pre> class App < E content_type :json # ... end </pre> <p>But what if you need to setup only specific actions?</p> <p>Simple! Put your setup, well, inside <code>setup</code> block and pass action names as parameters.</p> <p><strong>Example:</strong> Instruct <strong>only</strong> <code>rss</code> and <code>feed</code> actions to return XML Content-Type</p> <pre> class App < E setup :rss, :feed do content_type :xml end # ... end </pre> <p>Well, what if i need some setup for some 10 actions ad another setup for another 20 actions? Should i pass 30 arguments to <code>setup</code>? I do not want to buy a new keyboard every month...</p> <p>That's simple too. Use regular expressions.</p> <p>Ex: setup <strong>only</strong> news related actions:</p> <pre> class App < E setup /news/ do # some setup end # ... end </pre> <h2 id='slices'><a href='#slices'>Slices</a></h2> <p>Portability and DRY done right and easy.</p> <p>With Espresso, any controller can be mounted under any app.</p> <p>Even more, any set of controllers - a.k.a. <strong>slices</strong> - can be mounted under any app.</p> <p>To create a slice simply put your controllers under some module.</p> <p>Then you can mount that module under any Espresso app.</p> <p>Even more, when mounting you can easily setup all controllers(or some) at once.</p> <p>And of course when mounting, you can give a mount point.</p> <pre> module Cms class Articles < E # ... end class News < E # ... end class Pages < E # ... end end app = Cms.mount do # some setup that will run inside each controller end # or app = Cms.mount do |ctrl| # some setup that will run inside controllers that match `ctrl` param end app.run </pre> <h2 id='restful-actions'><a href='#restful-actions'>RESTful Actions</a></h2> <p>By default, verbless actions will respond to any request type.</p> <p>To make some action to respond only to some request type, simply prepend the corresponding verb to the action name.</p> <pre> # will respond to any request type def book # ... end # GET def get_book # ... end # POST def post_book # ... end # PUT def put_book # ... end # etc. </pre> <h2 id='flexible-rewriter'><a href='#flexible-rewriter'>Flexible Rewriter</a></h2> <p>With Espresso built-in rewriter you can redirect any requests to new URL.</p> <p>However, beside trivial redirects, rewriter can also pass the control to an arbitrary controller#action or simply halt the request and send the response.</p> <h2 id='views-compiler'><a href='#views-compiler'>Views Compiler</a></h2> <p>For most web sites, most time are spent at templates rendering.<br> When rendering templates, most time are spent at reading and compiling.</p> <p>Espresso allow to easily skip these expensive operations by keeping compiled templates in memory and just render them on consequent requests.</p> <h2 id='cache'><a href='#cache'>Cache</a></h2> <p>If you have some expensive operations that basically return static data, simply put them inside <code>cache</code> block.</p> <p>The result will be cached and returned on consequent requests.</p> <p>To clear cache, simply call <code>clear_cache!</code></p> <hr/> <footer class="footer well"> <div class="row"> <div class="span4"> <p> License: MIT </p> <p> Author: Silviu Rusu </p> <p> Source Code: <a href="https://github.com/espresso/espresso"> https://github.com/espresso/espresso</a> </p> </div> <div class="span6 pull-right"> <p> Issues/Bugs: <a href="https://github.com/espresso/espresso/issues"> https://github.com/espresso/espresso/issues</a> </p> <p> <strong>Contributors are very Welcome!</strong> </p> <p> IRC channel: #espressorb on irc.freenode.net </p> </div> </div> </footer> </div> <a href="https://github.com/espresso/espresso"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a> <script type="text/javascript"> $(function() { $('pre').addClass('prettyprint lang-ruby'); prettyPrint(); }); </script> <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-27879048-5']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> </body> </html>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.