Date post: | 27-Nov-2014 |
Category: |
Software |
Upload: | paul-seiffert |
View: | 239 times |
Download: | 1 times |
Symfony und Ember.js auf einer Seite
Paul SeiffertSensioLabs Deutschland GmbH
Klassische Webseiten
B R O W S E R
GET /
URL-Eingabe
HTMLWebseite
Link-Klick
Neue Webseite
…
GET /blog
HTML
S E R V E R
Klassische Webseiten
HTML
R O U T I N G
C O N T R O L L E R
S E C U R I T Y
T E M P L AT I N G
GET /
BusinessLogikS Y M F O N Y
Klassische Symfony-Seiten
Moderne Webseiten
Moderne Webseiten
View-Wechsel
B R O W S E R
GET /
URL-Eingabe
HTMLWebseite
Link-Klick
Neue Webseite
… S E R V E R
Moderne Webseiten
B R O W S E R
R O U T I N G
T E M P L AT I N G
C O N T R O L L E R
M O D E L
B R O W S E R
Moderne WebseitenR O U T I N G
T E M P L AT I N G
C O N T R O L L E R
M O D E L
GET /api/users
JSON
S E R V E R
Symfony und Ember.js auf einer Seite
Paul SeiffertSensioLabs Deutschland GmbH
– FA B I E N P O T E N C I E R
“Symfony2 is an HTTP framework;it is a Request/Response framework.”
B R O W S E RHTTP + Socket
GET /api/…Lokal
VM
S Y M F O N Y A P P
B R O W S E R
GET /api/…Lokal
Server
S Y M F O N Y A P P
W E B S E R V E R
GET /
D AT E I S Y S T E M
R O U T I N G
Wohin möchte der Benutzer?
posts: pattern: / methods: GET defaults: { _controller: BlogBundle:Post:index }post: pattern: /blog/{slug} methods: GET defaults: { _controller: BlogBundle:Post:detail }
Symfony Routing
#http://example.com blog/first-article/
var Router = Ember.Router.extend({ location: 'history'}); Router.map(function() { this.resource('blog', { path: '/' }, function () { this.route('post', { path: '/:slug' }); }); this.route('about'); });
PushState FTW!!Ember.js Routing
server { listen *:80;
server_name blog;
location / { root /opt/blog/dist; try_files $uri /index.html; index index.html; } }
Konfiguration
/api
location / { root /opt/blog/dist; try_files $uri /index.html; index index.html; }
/
/api/posts ⇒
/app.php/posts
/app.php/api
location ~ ^/api { root /opt/blog/web; try_files $uri @rewriteapp; index app.php; }
location @rewriteapp { rewrite ^/api/(.*)$ /app.php/$1 last; }
location ~ ^/(app|app_dev)\.php(/|$) { root /opt/blog/api/web; fastcgi_split_path_info /(.+\.php)(/.*)$; include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9001; }
M O D E L
ember data
var Post = DS.Model.extend({ title: DS.attr(), body: DS.attr(), date: DS.attr(), slug: DS.attr(), comments: DS.hasMany('comment', { async: true }), teaser: function () { return this.get('body').substr(0, 100); }.property('body') });
m o d e l s / p o s t . j s
S T O R E
A D A P T E R
J S A P P L I K AT I O N
R E S T F U L A P I
store.find('post', { slug: ‘awesome-blog-article‘})
GET /post?slug=awesome-blog-article
{ "post": [ { "id": 1, "title": “Mein erster Blog Post", "body": “Das der Inhalt meines ersten Blog-Posts“, "date": "2014-10-04T14:23:10+0200", "slug": "first-post", "links": { "comments": "/app_dev.php/api/posts/first-post/comments" } } ]}
GET /post?slug=awesome-blog-article
/first-post
Router.map(function() { this.resource('blog', { path: '/' }, function () { this.route('post', { path: '/:slug' }); }); });
ro u t e r. j s
ro u t e r. j s
var BlogPostRoute = Ember.Route.extend({ model: function (params) { return this.store.find('post', { slug: params.slug }); }, serialize: function(model) { return { slug: model.get('slug') }; } });
ro u t e s / b l o g / p o s t . j s
Router.map(function() { this.resource('blog', { path: '/' }, function () { this.route('post', { path: '/:slug' }); }); });
DS.RESTAdapter.extend({ namespace: ‘app_dev.php/api’ });
a d a p t e r s / a p p l i c a t i o n . j s
this.store.find('post')GET /app_dev.php/api/posts
this.store.find(‘post’, { slug: ‘first-post’ })GET /app_dev.php/api/posts?slug=first-post
this.store.find(‘post’, 1)GET /app_dev.php/api/posts/1
R E S T F U L A P I
C O N T R O L L E R
R E P O S I T O R Y
D ATA B A S E
R E S T F U L A P I
jms/serializer
willdurand/negotiation
symfony/symfony
willdurand/hateoas
⇒ http://www.slideshare.net/seiffertp
composer require
ember data
T E M P L AT I N G
<div class="container"> {{render 'navigation'}} <div class="container-fluid" id="content"> {{outlet}} </div></div>
a p p l i c a t i o n . h b s
<div class="blog-post"> <h1>{{#link-to 'blog.post' slug}}{{title}}{{/link-to}}</h1> <div class="blog-post-content"> {{body}} </div> <div class="blog-post-comments"> {{#each comments}} {{partial 'blog/comment'}} {{/each}} </div></div>{{#link-to 'blog.index'}}Zurück zur Liste{{/link-to}}
b l o g / p o s t . h b s
var Post = DS.Model.extend({ title: DS.attr(), body: DS.attr(), date: DS.attr(), slug: DS.attr(), comments: DS.hasMany('comment', { async: true }), teaser: function () { return this.get('body').substr(0, 100); }.property('body') });
m o d e l s / p o s t . j s
<div class="blog-post"> <h1>{{#link-to 'blog.post' slug}}{{title}}{{/link-to}}</h1> <div class="blog-post-content"> {{body}} </div> <div class="blog-post-comments"> {{#each comments}} {{partial 'blog/comment'}} {{/each}} </div></div>{{#link-to 'blog.index'}}Zurück zur Liste{{/link-to}}
b l o g / p o s t . h b s
T O O L S
$ ember serve —-proxy=http://symfony-api:80 version: 0.0.43 Proxying to http://symfony-api:80 Livereload server on port 35729 Serving on http://0.0.0.0:4200
$ npm install -g ember-cli
B R O W S E RHTTP + Socket
N G I N X
S Y M F O N Y A P P
GET /app_dev.php/api/…
P H P - F P M
D e v e l o p m e n t
Lokal
VagrantVM
B R O W S E R
N G I N X
S Y M F O N Y A P P
GET /api/…
P H P - F P M
P ro d u c t i o n
GET /
https://github.com/ seiffert/ember-symfony-blog
D A N K E !
F R A G E N ?