SlideShare a Scribd company logo
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...

PHP

Symfony 1.4
Doctrine
MySQL 

... and ideas from sfSimpleCMSPlugin
Goals of Apostrophe

Easy for clients to update without specialized training

Hard for clients to screw up by accident!

Extensible by any Symfony developer
Making it easy

"When you log in, it just gets awesomer"

Do things in context

When you can't do things in context, keep it simple

Don't require a degree in Drupal-ogy!

Check it out: demo.apostrophenow.com
... OK, but how do you extend it?

Relax! It's Still Symfony (RISS)

Apostrophe embraces Symfony idioms

Slot = Doctrine inheritance +       Engine = Symfony module +
          Edit view component +                    aRoute & aDoctrineRoute +
          Normal view component +                  Apostrophe page as a "host"
          Edit action +
          Edit form
Feed Slot: schema.yml

aFeedSlot:
  inheritance:
    extends: aSlot
    type: column_aggregation
    keyField: type
    keyValue: 'aFeed'
Feed Slot: edit view component

class 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());
    }
  }
  ...
}
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, ...);
       ...
     }
 }
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 ?>
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>
Feed Slot: edit action
class 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();
    }
  ...
Feed Slot: aFeedForm
class 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');
  }
}
apostrophe:generate-slot-type FTW!

./symfony apostrophe:generate-slot-type 
        --plugin=myPlugin 
        --type=monster

Generates:

schema.yml
Actions and components
monsterForm class

... Everything for a basic form-driven slot
Engines: multiple-page experiences

A Symfony module...

"Grafted" into the page tree

Multiple instances allowed

Easy to distinguish with categorized content

Examples: Bob's blog, Jane's blog, public photo gallery
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'));
    }
}
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-]+$ }
Media engine: routing examples

1. /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 iguana

3. /iguanapix/view/iguana ->
    Engine page /iguanapix
    Matches a_media_show route, slug is iguana
Bonus: safe, efficient JS calls + minifier
layout.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...'))); ?>
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Apostrophe 2.0
Conclusions

1.5 is awesome now

2.0 will be awesome later

You are awesome

Let's be awesome together
apostrophenow.com
     apostrophenow.com

More Related Content

What's hot

Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
Richard McIntyre
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
Fabien Potencier
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
Adam Trachtenberg
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes Presentation
Brent Shaffer
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?
Radek Benkel
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
Tammy Hart
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
patter
 
PHP an intro -1
PHP an intro -1PHP an intro -1
PHP an intro -1
Kanchilug
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
Andréia Bohner
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
Dan Jesus
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
Hugo Hamon
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
Radek Benkel
 
Keeping It Simple
Keeping It SimpleKeeping It Simple
Keeping It Simple
Stephanie Leary
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Balázs Tatár
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang
 
Add loop shortcode
Add loop shortcodeAdd loop shortcode
Add loop shortcode
Peter Baylies
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
Jeroen van Dijk
 

What's hot (19)

Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes Presentation
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
PHP an intro -1
PHP an intro -1PHP an intro -1
PHP an intro -1
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
 
Keeping It Simple
Keeping It SimpleKeeping It Simple
Keeping It Simple
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Add loop shortcode
Add loop shortcodeAdd loop shortcode
Add loop shortcode
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 

Similar to Apostrophe

関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
Leonardo Proietti
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
Lars Jankowfsky
 
Fatc
FatcFatc
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
Michael Peacock
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
Massimiliano Arione
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
Jeroen van Dijk
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Getting to The Loop - London Wordpress Meetup July 28th
Getting to The Loop - London Wordpress Meetup  July 28thGetting to The Loop - London Wordpress Meetup  July 28th
Getting to The Loop - London Wordpress Meetup July 28th
Chris Adams
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
D
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
Barang CK
 

Similar to Apostrophe (20)

関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Fatc
FatcFatc
Fatc
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Getting to The Loop - London Wordpress Meetup July 28th
Getting to The Loop - London Wordpress Meetup  July 28thGetting to The Loop - London Wordpress Meetup  July 28th
Getting to The Loop - London Wordpress Meetup July 28th
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 

Recently uploaded

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
SitimaJohn
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 

Recently uploaded (20)

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 

Apostrophe

  • 2. A Symfony-powered CMS your clients will love Thomas Boutell
  • 3. What is Apostrophe? Content Management System  Content Management Framework
  • 4. On the shoulders of giants... PHP Symfony 1.4 Doctrine MySQL  ... and ideas from sfSimpleCMSPlugin
  • 5. Goals of Apostrophe Easy for clients to update without specialized training Hard for clients to screw up by accident! Extensible by any Symfony developer
  • 6. Making it easy "When you log in, it just gets awesomer" Do things in context When you can't do things in context, keep it simple Don't require a degree in Drupal-ogy! Check it out: demo.apostrophenow.com
  • 7. ... OK, but how do you extend it? Relax! It's Still Symfony (RISS) Apostrophe embraces Symfony idioms Slot = Doctrine inheritance + Engine = Symfony module +           Edit view component +                aRoute & aDoctrineRoute +           Normal view component +                Apostrophe page as a "host"           Edit action +           Edit form
  • 8. Feed Slot: schema.yml aFeedSlot:   inheritance:     extends: aSlot     type: column_aggregation     keyField: type     keyValue: 'aFeed'
  • 9. Feed Slot: edit view component class 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. 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. 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. 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. Feed Slot: edit action class 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. Feed Slot: aFeedForm class 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. apostrophe:generate-slot-type FTW! ./symfony apostrophe:generate-slot-type          --plugin=myPlugin          --type=monster Generates: schema.yml Actions and components monsterForm class ... Everything for a basic form-driven slot
  • 16. Engines: multiple-page experiences A Symfony module... "Grafted" into the page tree Multiple instances allowed Easy to distinguish with categorized content Examples: Bob's blog, Jane's blog, public photo gallery
  • 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. 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. Media engine: routing examples 1. /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 iguana 3. /iguanapix/view/iguana ->     Engine page /iguanapix     Matches a_media_show route, slug is iguana
  • 20. Bonus: safe, efficient JS calls + minifier layout.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...'))); ?>
  • 28. Conclusions 1.5 is awesome now 2.0 will be awesome later You are awesome Let's be awesome together
  • 29. apostrophenow.com apostrophenow.com