Your SlideShare is downloading. ×
0
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Keeping it small: Getting to know the Slim micro framework

50,531

Published on

Published in: Technology
0 Comments
57 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
50,531
On Slideshare
0
From Embeds
0
Number of Embeds
34
Actions
Shares
0
Downloads
881
Comments
0
Likes
57
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • WTF?\n
  • Blame it on github and their repo name suggetsions\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Four views\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • Can be anything that returns true for is_callable()\n\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • GET, including route parameters and conditions\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • slim.before.router: after output buffering is turned on and before the router is dispatched. Once.\n\n
  • Has access to app, environment, request & response object\n
  • Has access to app, environment, request & response object\n
  • Has access to app, environment, request & response object\n
  • Has access to app, environment, request & response object\n
  • Has access to app, environment, request & response object\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • I won’t cover bootstrap, but it kicks ass\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Too much boilerplate to show off, but here come the important parts\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Keeping it smallGetting to know the Slim micro framework @JeremyKendall
    • 2. Jeremy Kendallraventools.com
    • 3. Jeremy Kendall I love to coderaventools.com
    • 4. Jeremy Kendall I love to code I’m terribly forgetfulraventools.com
    • 5. Jeremy Kendall I love to code I’m terribly forgetful I take picturesraventools.com
    • 6. Jeremy Kendall I love to code I’m terribly forgetful I take picturesraventools.com I work at Raven
    • 7. Micro framework?
    • 8. Micro framework?Concise codebase
    • 9. Micro framework?Concise codebaseClear codebase
    • 10. Micro framework?Concise codebaseClear codebaseAddresses a small set of use cases
    • 11. Micro framework?Concise codebaseClear codebaseAddresses a small set of use casesAddresses those use cases well
    • 12. What is Slim?
    • 13. What is Slim?Inspired by Sinatra
    • 14. What is Slim?Inspired by SinatraFavors cleanliness over terseness
    • 15. What is Slim?Inspired by SinatraFavors cleanliness over tersenessFavors common cases over edge cases
    • 16. Installing Slim
    • 17. RTFM
    • 18. RTFM ;-)
    • 19. Don’t forget .htaccess!RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^ index.php [QSA,L]http://docs.slimframework.com/pages/routing-url-rewriting/
    • 20. Hello world<?phprequire ../vendor/autoload.php;$app = new SlimSlim();$app->get(/hello/:name, function ($name) { echo "Hello, $name";});$app->run();
    • 21. Hello world<?phprequire ../vendor/autoload.php;$app = new SlimSlim();$app->get(/hello/:name, function ($name) { echo "Hello, $name";});$app->run();
    • 22. Hello world<?phprequire ../vendor/autoload.php;$app = new SlimSlim();$app->get(/hello/:name, function ($name) { echo "Hello, $name";});$app->run();
    • 23. Hello world<?phprequire ../vendor/autoload.php;$app = new SlimSlim();$app->get(/hello/:name, function ($name) { echo "Hello, $name";});$app->run();
    • 24. Hello world<?phprequire ../vendor/autoload.php;$app = new SlimSlim();$app->get(/hello/:name, function ($name) { echo "Hello, $name";});$app->run();
    • 25. Let’s look at aSlim application
    • 26. Flaming Archer
    • 27. Flaming Archer wat
    • 28. “Great repository names are short and memorable. Need inspiration? How about flaming-archer.”
    • 29. Flaming Archer
    • 30. Flaming ArcherPhoto 365 project
    • 31. Flaming ArcherPhoto 365 projectBuilt in 4 days (Saturday through Tuesday)
    • 32. Flaming ArcherPhoto 365 projectBuilt in 4 days (Saturday through Tuesday)Basic application — a few bells, no whistles
    • 33. Flaming ArcherPhoto 365 projectBuilt in 4 days (Saturday through Tuesday)Basic application — a few bells, no whistles Routing
    • 34. Flaming ArcherPhoto 365 projectBuilt in 4 days (Saturday through Tuesday)Basic application — a few bells, no whistles Routing Twig views
    • 35. Flaming ArcherPhoto 365 projectBuilt in 4 days (Saturday through Tuesday)Basic application — a few bells, no whistles Routing Twig views Middleware
    • 36. 4 views
    • 37. phploc --exclude vendor,tests,templates .phploc 1.6.4 by Sebastian Bergmann.Directories: 7Files: 13Lines of Code (LOC): 876 Cyclomatic Complexity / Lines of Code: 0.04Comment Lines of Code (CLOC): 272Non-Comment Lines of Code (NCLOC): 604
    • 38. Configuration
    • 39. return array( slim => array( templates.path => __DIR__ . /templates, log.level => 4, log.enabled => true, log.writer => new SlimExtrasLogDateTimeFileWriter( array( path => __DIR__ . /logs, name_format => y-m-d ) ) ), twig => array( // . . . ), cookies => array( // . . . ), flickr.api.key => FLICKR API KEY, pdo => array( // . . . ));
    • 40. return array( slim => array( templates.path => __DIR__ . /templates, log.level => 4, Slim log.enabled => true, log.writer => new SlimExtrasLogDateTimeFileWriter( array( path => __DIR__ . /logs, name_format => y-m-d ) ) ), twig => array( // . . . ), cookies => array( // . . . ), flickr.api.key => FLICKR API KEY, pdo => array( // . . . ));
    • 41. return array( slim => array( templates.path => __DIR__ . /templates, log.level => 4, Slim log.enabled => true, log.writer => new SlimExtrasLogDateTimeFileWriter( array( path => __DIR__ . /logs, name_format => y-m-d ) ) Views ), twig => array( // . . . ), cookies => array( // . . . ), flickr.api.key => FLICKR API KEY, pdo => array( // . . . ));
    • 42. return array( slim => array( templates.path => __DIR__ . /templates, log.level => 4, Slim log.enabled => true, log.writer => new SlimExtrasLogDateTimeFileWriter( array( path => __DIR__ . /logs, name_format => y-m-d ) ) Views ), twig => array( // . . . ), cookies => array( Cookies // . . . ), flickr.api.key => FLICKR API KEY, pdo => array( // . . . ));
    • 43. return array( slim => array( templates.path => __DIR__ . /templates, log.level => 4, Slim log.enabled => true, log.writer => new SlimExtrasLogDateTimeFileWriter( array( path => __DIR__ . /logs, name_format => y-m-d ) ) Views ), twig => array( // . . . ), cookies => array( Cookies // . . . ), flickr.api.key => FLICKR API KEY, pdo => array( // . . . ) My stuff);
    • 44. $config = require_once __DIR__ . /../config.php;// Prepare app$app = new SlimSlim($config[slim]);
    • 45. $config = require_once __DIR__ . /../config.php;// Prepare app$app = new SlimSlim($config[slim]); Config array goes here
    • 46. Routing
    • 47. Routing$app->get(/, function () use ($app, $service) { $images = $service->findAll(); $app->render(index.html, array(images => $images)); });
    • 48. RoutingHTTP Method $app->get(/, function () use ($app, $service) { $images = $service->findAll(); $app->render(index.html, array(images => $images)); } );
    • 49. Routing Resource URIHTTP Method $app->get(/, function () use ($app, $service) { $images = $service->findAll(); $app->render(index.html, array(images => $images)); } );
    • 50. Routing Resource URIHTTP Method Anonymous Function $app->get(/, function () use ($app, $service) { $images = $service->findAll(); $app->render(index.html, array(images => $images)); } );
    • 51. Routing$app->get(/, function () use ($app, $service) { $images = $service->findAll(); $app->render(index.html, array(images => $images)); });
    • 52. Routing$app->get(/, function () use ($app, $service) { Grabs all the pics $images = $service->findAll(); $app->render(index.html, array(images => $images)); });
    • 53. Routing$app->get(/, function () use ($app, $service) { Grabs all the pics $images = $service->findAll(); $app->render(index.html, array(images => $images)); }); Passes array of image data to index.html
    • 54. GET$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6])));
    • 55. GET URL parameter$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6])));
    • 56. GET ... gets passed as an URL parameter argument$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6])));
    • 57. GET ... gets passed as an URL parameter argument$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6]))); Condition
    • 58. GET ... gets passed as an URL parameter argument$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6]))); Condition 1 to 366
    • 59. GET$app->get(/:day, function($day) use ($app, $service) { $image = $service->find($day); if (!$image) { $app->notFound(); 404! } $app->render(images.html, $image); })->conditions(array(day => ([1-9]d?|[12]dd|3[0-5]d|36[0-6])));
    • 60. POST (with redirect)$app->post(/admin/add-photo, function() use ($app, $service) { $data = $app->request()->post(); $service->save($data); $app->redirect(/admin); });
    • 61. POST (with redirect)$app->post(/admin/add-photo, function() use ($app, $service) { $data = $app->request()->post(); $service->save($data); $app->redirect(/admin); } $_POST data is in); the request object
    • 62. POST (with redirect)$app->post(/admin/add-photo, function() use ($app, $service) { $data = $app->request()->post(); $service->save($data); $app->redirect(/admin); } $_POST data is in); the request object 302 Redirect
    • 63. Multiple methods$app->map(/login, function() { // Login })->via(GET, POST);
    • 64. Multiple methods Not an HTTP Method$app->map(/login, function() { // Login })->via(GET, POST);
    • 65. Multiple methods Not an HTTP Method$app->map(/login, function() { // Login })->via(GET, POST); via() is the awesome sauce
    • 66. Logging and flash messaging
    • 67. $app->post(/admin/clear-cache, function() use ($app) { $log = $app->getLog(); $cleared = null; $clear = $app->request()->post(clear); if ($clear == 1) { if (apc_clear_cache(user)) { $cleared = Cache was successfully cleared!; } else { $cleared = Cache was not cleared!; $log->error(Cache not cleared); } } $app->flash(cleared, $cleared); $app->redirect(/admin); });
    • 68. $app->post(/admin/clear-cache, function() use ($app) { $log = $app->getLog(); Get the log from $app $cleared = null; $clear = $app->request()->post(clear); if ($clear == 1) { if (apc_clear_cache(user)) { $cleared = Cache was successfully cleared!; } else { $cleared = Cache was not cleared!; $log->error(Cache not cleared); } } $app->flash(cleared, $cleared); $app->redirect(/admin); });
    • 69. $app->post(/admin/clear-cache, function() use ($app) { $log = $app->getLog(); Get the log from $app $cleared = null; $clear = $app->request()->post(clear); if ($clear == 1) { if (apc_clear_cache(user)) { $cleared = Cache was successfully cleared!; } else { $cleared = Cache was not cleared!; $log->error(Cache not cleared); Error! } } $app->flash(cleared, $cleared); $app->redirect(/admin); });
    • 70. $app->post(/admin/clear-cache, function() use ($app) { $log = $app->getLog(); Get the log from $app $cleared = null; $clear = $app->request()->post(clear); if ($clear == 1) { if (apc_clear_cache(user)) { $cleared = Cache was successfully cleared!; } else { $cleared = Cache was not cleared!; $log->error(Cache not cleared); Error! } } $app->flash(cleared, $cleared); Flash message available in $app->redirect(/admin); the next request. });
    • 71. Middleware“The purpose of middleware is to inspect,analyze, or modify the applicationenvironment, request, and response beforeand/or after the Slim application isinvoked.” http://docs.slimframework.com/pages/middleware-overview/
    • 72. Hooks
    • 73. Hooksslim.before
    • 74. Hooksslim.beforeslim.before.router
    • 75. Hooksslim.beforeslim.before.routerslim.before.dispatch
    • 76. Hooksslim.before slim.after.dispatchslim.before.routerslim.before.dispatch
    • 77. Hooksslim.before slim.after.dispatchslim.before.router slim.after.routerslim.before.dispatch
    • 78. Hooksslim.before slim.after.dispatchslim.before.router slim.after.routerslim.before.dispatch slim.after
    • 79. Hooksslim.before slim.after.dispatchslim.before.router slim.after.routerslim.before.dispatch slim.after
    • 80. class MyMiddleware extends SlimMiddleware{ public function call() { //The Slim application $app = $this->app; //The Environment object $env = $app->environment(); //The Request object $req = $app->request(); //The Response object $res = $app->response(); //Optionally call the next middleware $this->next->call(); }}
    • 81. class MyMiddleware extends SlimMiddleware Extend this{ public function call() { //The Slim application $app = $this->app; //The Environment object $env = $app->environment(); //The Request object $req = $app->request(); //The Response object $res = $app->response(); //Optionally call the next middleware $this->next->call(); }}
    • 82. class MyMiddleware extends SlimMiddleware Extend this{ public function call() { Define call() //The Slim application $app = $this->app; //The Environment object $env = $app->environment(); //The Request object $req = $app->request(); //The Response object $res = $app->response(); //Optionally call the next middleware $this->next->call(); }}
    • 83. class MyMiddleware extends SlimMiddleware Extend this{ public function call() { Define call() //The Slim application $app = $this->app; //The Environment object $env = $app->environment(); Inspect, analyze, and modify! //The Request object $req = $app->request(); //The Response object $res = $app->response(); //Optionally call the next middleware $this->next->call(); }}
    • 84. class MyMiddleware extends SlimMiddleware Extend this{ public function call() { Define call() //The Slim application $app = $this->app; //The Environment object $env = $app->environment(); Inspect, analyze, and modify! //The Request object $req = $app->request(); //The Response object $res = $app->response(); //Optionally call the next middleware $this->next->call(); On to the next! }}
    • 85. Middleware + Hooks = WIN
    • 86. Navigation example
    • 87. namespace TsfMiddleware;use ZendAuthenticationAuthenticationService;class Navigation extends SlimMiddleware{ /** * @var ZendAuthenticationAuthenticationService */ private $auth; public function __construct(AuthenticationService $auth) { $this->auth = $auth; } public function call() { // . . . }}
    • 88. namespace TsfMiddleware;use ZendAuthenticationAuthenticationService;class Navigation extends SlimMiddleware extends{ /** * @var ZendAuthenticationAuthenticationService */ private $auth; public function __construct(AuthenticationService $auth) { $this->auth = $auth; } public function call() { // . . . }}
    • 89. namespace TsfMiddleware;use ZendAuthenticationAuthenticationService;class Navigation extends SlimMiddleware extends{ /** * @var ZendAuthenticationAuthenticationService */ private $auth; public function __construct(AuthenticationService $auth) { $this->auth = $auth; } Constructor injection public function call() FTW { // . . . }}
    • 90. public function call(){ $app = $this->app; $auth = $this->auth; $req = $app->request(); $home = array(caption => Home, href => /); $admin = array(caption => Admin, href => /admin); $login = array(caption => Login, href => /login); $logout = array(caption => Logout, href => /logout); if ($auth->hasIdentity()) { $navigation = array($home, $admin, $logout); } else { $navigation = array($home, $login); } // . . .}
    • 91. public function call(){ $app = $this->app; Arrays of $auth = $this->auth; nav items $req = $app->request(); $home = array(caption => Home, href => /); $admin = array(caption => Admin, href => /admin); $login = array(caption => Login, href => /login); $logout = array(caption => Logout, href => /logout); if ($auth->hasIdentity()) { $navigation = array($home, $admin, $logout); } else { $navigation = array($home, $login); } // . . .}
    • 92. public function call(){ $app = $this->app; Arrays of $auth = $this->auth; nav items $req = $app->request(); $home = array(caption => Home, href => /); $admin = array(caption => Admin, href => /admin); $login = array(caption => Login, href => /login); $logout = array(caption => Logout, href => /logout); if ($auth->hasIdentity()) { $navigation = array($home, $admin, $logout); } else { $navigation = array($home, $login); } Nav differs based // . . . on auth status}
    • 93. public function call(){ // . . . $this->app->hook(slim.before.router, function () use (...) { foreach ($navigation as &$link) { if ($link[href] == $req->getPath()) { $link[class] = active; } else { $link[class] = ; } } $app->view() ->appendData(array(navigation => $navigation)); } ); $this->next->call();}
    • 94. public function call(){ Delicious hook // . . . goodness $this->app->hook(slim.before.router, function () use (...) { foreach ($navigation as &$link) { if ($link[href] == $req->getPath()) { $link[class] = active; } else { $link[class] = ; } } $app->view() ->appendData(array(navigation => $navigation)); } ); $this->next->call();}
    • 95. public function call(){ Delicious hook // . . . goodness $this->app->hook(slim.before.router, function () use (...) { foreach ($navigation as &$link) { if ($link[href] == $req->getPath()) { $link[class] = active; } else { $link[class] = ; } Match } dispatched path $app->view() ->appendData(array(navigation => $navigation)); } ); $this->next->call();}
    • 96. public function call(){ Delicious hook // . . . goodness $this->app->hook(slim.before.router, function () use (...) { foreach ($navigation as &$link) { if ($link[href] == $req->getPath()) { $link[class] = active; } else { $link[class] = ; } Match } dispatched path $app->view() ->appendData(array(navigation => $navigation)); } ); Append $navigation to $this->next->call();} view
    • 97. public function call(){ Delicious hook // . . . goodness $this->app->hook(slim.before.router, function () use (...) { foreach ($navigation as &$link) { if ($link[href] == $req->getPath()) { $link[class] = active; } else { $link[class] = ; } Match } dispatched path $app->view() ->appendData(array(navigation => $navigation)); } ); Append $navigation to $this->next->call(); On to the next!} view
    • 98. Views
    • 99. Two great tastesthat taste great together
    • 100. Twig
    • 101. TwigConcise
    • 102. TwigConciseTemplate oriented
    • 103. TwigConciseTemplate orientedFast
    • 104. TwigConcise Multiple inheritanceTemplate orientedFast
    • 105. TwigConcise Multiple inheritanceTemplate oriented BlocksFast
    • 106. TwigConcise Multiple inheritanceTemplate oriented BlocksFast Automatic escaping
    • 107. layout.html andindex.html
    • 108. layout.html
    • 109. <title>{% block page_title %} {% endblock %}</title>
    • 110. <ul class="nav"> {% for link in navigation %} <li class="{{link.class}}"> <a href="{{link.href}}">{{link.caption}}</a> </li> {% endfor %}</ul>
    • 111. <h1>365 Days of Photography</h1><h3>Photographer: Jeremy Kendall</h3>{% block content %} {% endblock %}<hr />
    • 112. index.html
    • 113. {% extends layout.html %}{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %}{% for image in images %}<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div>{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 114. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %}{% for image in images %}<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div>{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 115. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %} <title />{% for image in images %}<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div>{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 116. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %} <title />{% for image in images %}<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div>{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 117. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %} <title />{% for image in images %} iterator<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div>{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 118. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %} <title />{% for image in images %} iterator<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div> else{% else %}<p>No images in project</p>{% endfor %}{% endblock %}
    • 119. {% extends layout.html %} extends{% block page_title %}365.jeremykendall.net{% endblock %}{% block content %} <title />{% for image in images %} iterator<div class="row"> <div class="span6"> <h2><a href="/{{image.day}}">{{image.day}}/365</a></h2> <p> <a href="/{{image.day}}"> <img src="{{image.sizes.size.5.source}}" /> </a> </p> <p>Posted {{image.posted|date("m/d/Y")}}</p> </div></div> else{% else %}<p>No images in project</p> format{% endfor %}{% endblock %}
    • 120. login.html
    • 121. {% extends layout.html %}{% block page_title %}365.jeremykendall.net | Login{% endblock %}{% block content %}<div class="row"> <div class="span4"> <h2>Login</h2> {% if flash.error %} <p style="color: red;">{{flash.error}}</p> {% endif %} <form name="login" id="login" class="well" method="post"> // Login form . . . </form> </div></div>{% endblock %}
    • 122. {% extends layout.html %}{% block page_title %}365.jeremykendall.net | Login{% endblock %}{% block content %}<div class="row"> <div class="span4"> <h2>Login</h2> {% if flash.error %} <p style="color: red;">{{flash.error}}</p> {% endif %} <form name="login" id="login" class="well" method="post"> // Login form . . . </form> </div></div>{% endblock %}
    • 123. The other viewswould be redundant
    • 124. GOTO 0
    • 125. Small but powerful GOTO 0
    • 126. Small but powerful GOTO 0Excellent tools to write elegant code
    • 127. Small but powerful GOTO 0Excellent tools to write elegant codeRouting, middleware & hooks, views
    • 128. Small but powerful GOTO 0Excellent tools to write elegant codeRouting, middleware & hooks, viewsI just scratched the surface
    • 129. ReadSlim: slimframework.comTwig: twig.sensiolabs.orgComposer: getcomposer.orgMicroPHP Manifesto: microphp.orgFlaming Archer: http://git.io/rH0nrg
    • 130. Questions?
    • 131. Thanks!jeremy@jeremykendall.net @jeremykendall

    ×