SymfonyCon Cluj 2017: Batteries included! Thanks to symfony.

SymfonyCon Cluj 2017: Batteries included! Thanks to symfony.

Ef5454d85ade16ae68c3ba1494f3bbaf?s=128

Wachter Johannes

November 17, 2017
Tweet

Transcript

  1. Tired of fixing your CMS 
 instead of creating awesome

    websites? Batteries included! Thanks to Symfony.
  2. I'm Johannes Wachter @wachterjohannes | https://asapo.at | https://github.com/wachterjohannes ... core

    developer and support genius. Never looses his smile, even on release days.
  3. Who knows Sulu?

  4. Sulu – Content Management Platform – Full-Stack Symfony – Made

    for businesses – Simple UI – High Performance – Open Source
  5. Where we see us Bicycles Everyone can ride them, many

    can repair it
 (WordPress etc.) Cars Many can ride them, some can repair it
 (Typo3 etc.) Supertanker Need highly specialized staff, expensive and very complex
 (Hybris, OpenText etc.) – Trucks Need a special license, must be configured to your needs
 (EZpublisher, PimCore etc.)
  6. Getting Started The basic architecture and concepts of Sulu.

  7. PHPCR DOCTRINE MySQL, PostgreSQL, Jackrabbit, ... Framework Symfony Symfony CMF

    Contact Media Content ... Sulu
  8. REST API Single-Page Application Your Application Website Admin Symfony Symfony

    CMF Contact Media Content ... Sulu
  9. None
  10. <webspace> <name>example.com</name> <key>example</key> <localizations> <localization language="en" default="true"/> <localization language="de" country="at"/>

    </localizations> <portals> <portal> <name>example.com</name> <key>example</key> <environments> <environment type="prod"> <urls> <url>example.com/{localization}</url> </urls> </environment> <environment type="dev"> <urls> <url>{host}/{localization}</url> </urls> </environment> </environments> </portal>
  11. Templates & Content Types – The structure of the page

    – How that structure is rendered – Each page template is defined by two files: – an XML file that contains the page structure – a Twig file that contains the HTML code – A page structure consists of properties, each of which has a content type
  12. <?xml version="1.0" ?> <template xmlns="http://schemas.sulu.io/template/template" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/ template/template-1.0.xsd"> <key>default</key>

    <view>templates/default</view> <controller>SuluWebsiteBundle:Default:index</controller> <cacheLifetime>2400</cacheLifetime> <properties> <section name="highlight"> <properties> <property name="title" type="text_line" mandatory="true"> <tag name="sulu.rlp.part"/> </property> <property name="url" type="resource_locator" mandatory="true"> <tag name="sulu.rlp"/> </property> </properties> </section> <property name="article" type="text_editor"/> </properties> </template>
  13. {% extends "master.html.twig" %} {% block content %} <h1 property="title">{{

    content.title }}</h1> <div property="article"> {{ content.article|raw }} </div> {% endblock %}
  14. Content Types ... Live Preview ...

  15. None
  16. Router The main entry point to your Symfony application.

  17. / /services /blog Request Response Kernel Controller Router Request URI

    Controller & Action Front Controller indexAction() servicesAction blogAction() Response Response Response Model View Services
  18. Router Chain Router / /services /blog Request Response Kernel Controller

    Request URI Controller & Action Front Controller indexAction() servicesAction blogAction() Response Response Response Model View Services Dynamic Router
  19. Sulu routing summarized – CMF ChainRouter replaces the default routing

    system – and works by accepting a set of prioritized Routers – The Symfony default Router is registered with the highest priority – DynamicRouters handle all the dynamically defined routes (pages, redirects, …)
  20. // app/WebsiteKernel.php
 
 class WebsiteKernel extends AbstractKernel
 {
 /**
 *

    {@inheritdoc}
 */
 protected $name = 'website';
 
 /**
 * @param string $environment
 * @param bool $debug
 */
 public function __construct($environment, $debug)
 {
 parent::__construct($environment, $debug);
 $this->setContext(self::CONTEXT_WEBSITE);
 }
 
 /**
 * {@inheritdoc}
 */
 public function registerBundles()
 {
 $bundles = parent::registerBundles();
 $bundles[] = new Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle();
 return $bundles;
 }
 } $bundles[] = new AppBundle\AppBundle();
  21. // app/config/website/routing.yml app:
 resource: "@AppBundle/Controller/"
 type: annotation
 prefix: /app //

    src/AppBundle/Controller/DefaultController.php namespace AppBundle\Controller;
 
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 
 class DefaultController extends Controller
 {
 /**
 * @Route("/")
 */
 public function indexAction()
 {
 return $this->render('AppBundle:Default:index.html.twig');
 }
 } // src/AppBundle/Resources/views/Default/index.html.twig Hallo World!
  22. None
  23. Controller & View Add your custom logic within your own

    content Controller.
  24. Controller Chain Router Router / /services /blog Request Response Kernel

    Request URI Controller & Action Front Controller indexAction() servicesAction blogAction() Response Response Response Model View Services Dynamic Router Default Controller
  25. // app/Resources/templates/pages/default.xml <?xml version="1.0" ?>
 <template xmlns="http://schemas.sulu.io/template/template"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://schemas.sulu.io/template/template http://

    schemas.sulu.io/template/template-1.0.xsd">
 
 <key>default</key>
 
 <view>templates/default</view> 
 <cacheLifetime>2400</cacheLifetime>
 
 <meta>
 <title lang="en">Default</title>
 <title lang="de">Standard</title>
 </meta>
 
 ... </template>
 <controller>AppBundle:Custom:index</controller>
  26. // src/AppBundle/Controller/CustomController.php
 
 namespace AppBundle\Controller;
 
 use Sulu\Bundle\WebsiteBundle\Controller\WebsiteController;
 use Sulu\Component\Content\Compat\StructureInterface;


    
 class CustomController extends WebsiteController
 {
 /**
 * My custom controller action.
 *
 * @param StructureInterface $structure
 * @param bool $preview
 * @param bool $partial
 *
 * @return Response
 */
 public function indexAction(StructureInterface $structure, $preview = false, $partial = false)
 {
 $response = $this->renderStructure(
 $structure,
 [
 // here you can add some custom data for your template
 'myData' => $this->get('my_custom_service')->getMyData(),
 ],
 $preview,
 $partial
 );
 
 return $response;
 }
 }
  27. Response Format HTML, XML or JSON

  28. // app/Resources/templates/pages/default.xml <?xml version="1.0" ?>
 <template xmlns="http://schemas.sulu.io/template/template"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd">


    
 <key>default</key>
 
 <view>AppBundle:Custom:index</view>
 <controller>AppBundle:Custom:index</controller>
 <cacheLifetime>2400</cacheLifetime>
 
 ... </template> // src/AppBundle/Resources/views/Custom/index.html.twig
 
 {% extends "master.html.twig" %}
 
 {% block content %}
 <h1 property="title">{{ content.title }}</h1>
 
 <div property="article">
 {{ content.article|raw }}
 </div>
 {% endblock %} // src/AppBundle/Resources/views/Custom/index.json.twig {{ content|json_encode|raw }} .html.twig
  29. None
  30. Event Dispatcher Handle additional business logic within your Event Subscriber.

  31. Symfony Events Kernel Events – kernel.request – kernel.response – kernel.controller

    – kernel.view – kernel.terminate … Doctrine Events Lifecycle Events – [pre|post]Remove – [pre|post]Persist – [pre|post]Update – [pre|on|post]Flush – onClear …
  32. Sulu Document Manager Events +----------------------+ | Events | +----------------------+ |

    persist | | hydrate | | remove | | refresh | | copy | | move | | create | | clear | | find | | reorder | | publish | | unpublish | | remove_draft | | flush | | query.create | | query.create_builder | | query.execute | | configure_options | | metadata_load | | restore | +----------------------+ bin/adminconsole sulu:document:subscriber:debug
  33. // src/AppBundle/Document/Subscriber/MailSubscriber.php
 
 namespace AppBundle\Document\Subscriber;
 
 use Sulu\Component\DocumentManager\Event\PublishEvent;
 use Sulu\Component\DocumentManager\Events;


    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 class MailSubscriber implements EventSubscriberInterface
 {
 ...
 
 /**
 * {@inheritdoc}
 */
 public static function getSubscribedEvents()
 {
 return [
 Events::PUBLISH => ['sendNotification', -1000],
 ];
 }
 
 public function sendNotification(PublishEvent $event)
 {
 $message = new \Swift_Message('Page Published', 'URL: ' . $event->getDocument()->getResourceSegment());
 
 $this->mailer->send($message);
 }
 } <service id="app.document_subscriber.email" class="AppBundle\Document\Subscriber\MailSubscriber"> <argument type="service" id="mailer" /> <tag name="sulu_document_manager.event_subscriber"/> </service>
  34. Service Container The control center for all you application.

  35. Service Container – Foundation for extensibility & customizability – Sulu

    heavily uses service definitions – Add new functionality (Modulnavigation, Content-Type, ...) – Extend existing (Smart-Content, Teaser, ...) – Overwrite services
  36. Case Studies

  37. https://www.stickermanager.com

  38. https://www.stickermanager.com

  39. https://www.kuechengoetter.de

  40. Thanks for watching! www.sulu.io www.github.com/sulu