apostrophenow.com / punkave.com
A Symfony-powered CMS   your clients will love     Thomas Boutell
What is Apostrophe?Content Management System Content Management Framework
On the shoulders of giants...PHPSymfony 1.4DoctrineMySQL ... and ideas from sfSimpleCMSPlugin
Goals of ApostropheEasy for clients to update without specialized trainingHard for clients to screw up by accident!Extensi...
Making it easy"When you log in, it just gets awesomer"Do things in contextWhen you cant do things in context, keep it simp...
... OK, but how do you extend it?Relax! Its Still Symfony (RISS)Apostrophe embraces Symfony idiomsSlot = Doctrine inherita...
Feed Slot: schema.ymlaFeedSlot:  inheritance:    extends: aSlot    type: column_aggregation    keyField: type    keyValue:...
Feed Slot: edit view componentclass BaseaFeedSlotComponents extends aSlotComponents{  public function executeEditView()  {...
Feed Slot: normal view component...public function executeNormalView() {    $this->setup();    $this->values = $this->slot...
Feed Slot: edit view partial<?php use_helper(a) ?><ul class="a-slot-info a-feed-info">  <li><?php echo a_(Paste an RSS fee...
Feed Slot: normal view partial<?php use_helper(a) ?><?php if ($editable): ?>  <?php // Display the edit button ?>  <?php i...
Feed Slot: edit actionclass aFeedSlotActions extends aSlotActions{  public function executeEdit(sfRequest $request)  {    ...
Feed Slot: aFeedFormclass aFeedForm extends BaseForm{  public function __construct($id = 1, $defaults = array())  {    $th...
apostrophe:generate-slot-type FTW!./symfony apostrophe:generate-slot-type         --plugin=myPlugin         --type=monster...
Engines: multiple-page experiencesA Symfony module..."Grafted" into the page treeMultiple instances allowedEasy to disting...
Media engine: actions class (simplified)class BaseaMediaActions extends aEngineActions{  public function executeIndex(sfWeb...
Media engine: routing (yml style)a_media_index:  url: /  class: aRoute  param: { module: aMedia, action: index }a_media_sh...
Media engine: routing examples1. /admin/media ->     Engine page /admin/media    Matches a_media_index route (special case...
Bonus: safe, efficient JS calls + minifierlayout.php:<head><?php a_use_javascripts() ?><?php a_use_stylesheets() ?></head><b...
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Conclusions1.5 is awesome now2.0 will be awesome laterYou are awesomeLets be awesome together
apostrophenow.com     apostrophenow.com
Upcoming SlideShare
Loading in …5
×

Apostrophe

9,384 views

Published on

A content management system your clients and developers will both be happy with. Open source, built on the Symfony MVC framework. Slides from Symfony Live 2011 in San Francisco

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
9,384
On SlideShare
0
From Embeds
0
Number of Embeds
2,251
Actions
Shares
0
Downloads
58
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Apostrophe

  1. 1. apostrophenow.com / punkave.com
  2. 2. A Symfony-powered CMS your clients will love Thomas Boutell
  3. 3. What is Apostrophe?Content Management System Content Management Framework
  4. 4. On the shoulders of giants...PHPSymfony 1.4DoctrineMySQL ... and ideas from sfSimpleCMSPlugin
  5. 5. Goals of ApostropheEasy for clients to update without specialized trainingHard for clients to screw up by accident!Extensible by any Symfony developer
  6. 6. Making it easy"When you log in, it just gets awesomer"Do things in contextWhen you cant do things in context, keep it simpleDont require a degree in Drupal-ogy!Check it out: demo.apostrophenow.com
  7. 7. ... OK, but how do you extend it?Relax! Its Still Symfony (RISS)Apostrophe embraces Symfony idiomsSlot = Doctrine inheritance + Engine = Symfony module +          Edit view component +                aRoute & aDoctrineRoute +          Normal view component +                Apostrophe page as a "host"          Edit action +          Edit form
  8. 8. Feed Slot: schema.ymlaFeedSlot:  inheritance:    extends: aSlot    type: column_aggregation    keyField: type    keyValue: aFeed
  9. 9. Feed Slot: edit view componentclass BaseaFeedSlotComponents extends aSlotComponents{ public function executeEditView() { $this->setup(); // If this is the first validation pass make the form if (!isset($this->form)) { $this->form = new aFeedForm($this->id, $this->slot->getArrayValue()); } } ...}
  10. 10. Feed Slot: normal view component...public function executeNormalView() { $this->setup(); $this->values = $this->slot->getArrayValue(); if (!empty($this->values[url])) { $this->feed = aFeed::fetchCachedFeed( $this->url, ...); ... } }
  11. 11. Feed Slot: edit view partial<?php use_helper(a) ?><ul class="a-slot-info a-feed-info"> <li><?php echo a_(Paste an RSS feed URL, a Twitter @name (with the @), .or the URL of a page that offers a feed. Most blogs do.) ?></li></ul><?php echo $form ?>
  12. 12. Feed Slot: normal view partial<?php use_helper(a) ?><?php if ($editable): ?> <?php // Display the edit button ?> <?php include_partial(a/simpleEditWithVariants, ... ) ?><?php endif ?><ul class="a-feed"> <?php foreach ($feed->getItems() as $feedItem): ?> <?php include_partial(aFeedSlot/.$options[itemTemplate], array(feedItem => $feedItem, ... )) ?> <?php endforeach ?></ul>
  13. 13. Feed Slot: edit actionclass aFeedSlotActions extends aSlotActions{ public function executeEdit(sfRequest $request) { $this->editSetup(); $value = $this->getRequestParameter(slot-form- . $this->id); $this->form = new aFeedForm($this->id, array()); $this->form->bind($value); if ($this->form->isValid()) { // Serialize usually better than extra db columns $this->slot->setArrayValue($this->form->getValues()); return $this->editSave(); } else { // Another validation pass return $this->editRetry(); } ...
  14. 14. Feed Slot: aFeedFormclass aFeedForm extends BaseForm{ public function __construct($id = 1, $defaults = array()) { $this->id = $id; parent::__construct(); $this->setDefaults($defaults); } public function configure() { $this->setWidget(url, new sfWidgetFormInputText( array(label => RSS Feed URL)))); // Validators for: Twitter handle, lazy URLs, // valid URLs, regular pages with feed URLs in meta tags $this->widgetSchema->setNameFormat(slot-form- . $this->id . [%s]); $this->widgetSchema->setFormFormatterName(aAdmin); }}
  15. 15. apostrophe:generate-slot-type FTW!./symfony apostrophe:generate-slot-type         --plugin=myPlugin         --type=monsterGenerates:schema.ymlActions and componentsmonsterForm class... Everything for a basic form-driven slot
  16. 16. Engines: multiple-page experiencesA Symfony module..."Grafted" into the page treeMultiple instances allowedEasy to distinguish with categorized contentExamples: Bobs blog, Janes blog, public photo gallery
  17. 17. Media engine: actions class (simplified)class BaseaMediaActions extends aEngineActions{ public function executeIndex(sfWebRequest $request) { $this->items = Doctrine::getTable(aMediaItem)->findAll(); } public function executeShow(sfWebRequest $request) { $this->item = Doctrine::getTable(aMediaItem) ->findOneBySlug($request->getParameter(slug)); }}
  18. 18. Media engine: routing (yml style)a_media_index: url: / class: aRoute param: { module: aMedia, action: index }a_media_show: url: /view/:slug class: aRoute param: { module: aMedia, action: show } requirements: { slug: ^[w-]+$ }
  19. 19. Media engine: routing examples1. /admin/media ->     Engine page /admin/media    Matches a_media_index route (special case for /)2. /admin/media/view/iguana ->     Engine page /admin/media     Matches a_media_show route, slug is iguana3. /iguanapix/view/iguana ->    Engine page /iguanapix    Matches a_media_show route, slug is iguana
  20. 20. Bonus: safe, efficient JS calls + minifierlayout.php:<head><?php a_use_javascripts() ?><?php a_use_stylesheets() ?></head><body>... At the very END of the body:<?php a_include_js_calls() ?></body>_list_footer.php:<?php a_js_call(apostrophe.enableUserAdmin(?), array(choose-one-label => a_(Choose One...))); ?>
  21. 21. Apostrophe 2.0
  22. 22. Apostrophe 2.0
  23. 23. Apostrophe 2.0
  24. 24. Apostrophe 2.0
  25. 25. Apostrophe 2.0
  26. 26. Apostrophe 2.0
  27. 27. Apostrophe 2.0
  28. 28. Conclusions1.5 is awesome now2.0 will be awesome laterYou are awesomeLets be awesome together
  29. 29. apostrophenow.com apostrophenow.com

×