+ {{ news.title|capitalize }} + {{ news.date|date('d/m/Y') }} +
+{{ news.headline }}
+ {% if news.body is not empty %} + + {% endif %} +diff --git a/docs/en/1_introduction/1_preamble.html b/docs/en/1_introduction/1_preamble.html new file mode 100644 index 0000000..ee3d569 --- /dev/null +++ b/docs/en/1_introduction/1_preamble.html @@ -0,0 +1,552 @@ + + + +
+ + +First of all, let's start by stating the obvious: today, we develop fewer websites which fit with the historical CMS favour of web app development. These latters are rich in interactions, management rules and interconnections, everything a framework can handle.
+Synapse has been developed with one main purpose : being an additional offer in the jungle of the open source content management projects, but business development centred, combining of the best of these two worlds :
+However, as the old sayings goes "there's no silver bullet" in computing : the compromise on which Synapse is based force it to take no business decision but for the content management. In other words, the work needed to fill up the project is more important. +Conseqnently: Synapse can fit to the creation of a showcase website, but it will bring no plus-value compared to the other solutions, lighter in installation and exploitation. Nevertheless, if the showcase is just the first step of a bigger project - as a company can do for a multi connected e-commerce website - Synapse is the way to do it.
+Let's take time to reconsider a controversial subject, the following statment "I won't reinvent the wheel". +This old saying does not suit to the web of today, it's a fact. Don't reinventing the wheel means we will always check if anyone else has already developed and published a project we are close to begin. We often find it. Very often. At least, we find something slightly different. But once we found it, the wheel can work wrong.But it is neither the mecanician's fault, nor the pilot's. The problem is somewhere else: no wheel can fit to the needs of the pilot.
+Today, on the web, successful people are the those who think up, who innovate, who have a efficient and reliable operating system. They need to master their information system. However, each module delivering a business service brings technical debt in the system: if the company innovates, the module will not fit to the need anymore and will be replaced. This is often expensive, furthermore if some dependencies from the rest of the system are involved. +Let's take a step back from this statement : what if not only the wheel, but the whole vehicle which are not invented ? Everything potentially needs to be redone. But, as long as we can drive in city, no issue. Concerning driving on a circuit, there is a step.
+It is there Synapse creates value : no wheel is proposed but tools to build your own. It takes time and energ to build a wheel. But this wheel will fit to the driver.
+Here we close the"custom vs out-of-the-box" debate.
+The second principle is actually a corollary of the former principle : if Synapse is designed to let the developer use their skills, it is obvious that Synapse must offer simple and efficient APIs, middlewares, configurations, logs and debug tools. All these notions, called "Developer experience", or DX, are already some of the priorities of the framework Symfony.
+Synapse owns a non-intrusive interface with the rest of the project, systematically fostering decoupling, sometimes costing more complexity to stay in the isolation logic, in order to avoid side-effects and intempestive dependencies.
+To conclude and sum up previous outlined isseues, Synapse is oriented for "custom" project developers who don't want to be part of the wheel of a whole system. Synapse suits to any projects, particularly to applications with plenty of management rules.
+ + +Let's go into further details : how Synapse allows to have a strong content management without strong coupling ? +Firstly, it is thanks to the two popular design patterns, particularly in Symfony : Deorator (Templating component) and Prototype (Form component). +On the other hand, it is thanks to a SOLID based design, especially the mastery of object dependencies.
+The Synapse model is built from these two design patterns, detailled in the next rubrics.
+As previously described, Synapse is non-intrusive for the project which includes it. +To that end, an inversion of control is implemented between business objects and the Synapse model, through the notion of content type.
+Traditionnally, when it is possible to implement custom models, it results to hard code the include of the librarie in the business model, either by abstract class / inheritance, or by composition. In both cases, the business model is hardly linked to the librarie : dedicated methods are implemented, thereby the architecture include a constrainst.
+Synapse take the counter of these habits by throwing off the strong bond with the business object : it will never directly take action, it just decorate the object through its own model. The decorated object must just implement the interface, and be referenced in a configuration (refer to content type configuration).
+Then, it is possible to decorate any business object thanks to Synapse without corrupt its software entity, from the simple web page (like in the PageBundle disctribution), to an press article, going through e-commerce products with plenty of fields and/or dependencies.
+The DX (Developer eXperience) come from a task sharing between coworkers too. The frameworks let each person work efficientely on his task.
+In a standard team organisation, containing designers, web integrators and backend developers, mockups are designed by the design team, then integrated in HTML/CSS (and more) by frontend team, and finally "brought to life" by the backend team.
+Synapse allows the team to simplify the process by setting up a prototyping of the rendering of content types through simple configuration file, formatted in Yaml.
+So, the workflow becomes :
+This prototyping gives to the team more flexibility to work in parallel than the classic system, bacause it leads to a decoupling. In detail :
+From a macroscopic view, thanks to the prototyping, the team will be able to change a whol theme without involving a heavy backend development, as long as the data and component configurations stand still.
+ + +The standard edition of Synapste is work in progress.
+First of all, please create a Symfony project, then please follow the installation process for an existing project.
+ + +The installation works with Composer, as many Symfony bundles do? +You also need a Sql database to store Synapse Cmf data.
+In the first place, you need to add the Synapse Cmf bundles to your project :
+composer require synapse-cmf/synapse-cmf ~1.0@dev
+
+Then, include them in your kernel application :
+// app/AppKernel.php
+
+class AppKernel extends Kernel
+{
+ public function registerBundles()
+ {
+ $bundles = [
+ // dependencies
+ new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
+ new Majora\Bundle\FrameworkExtraBundle\MajoraFrameworkExtraBundle($this),
+
+ // core
+ new Synapse\Cmf\Bundle\SynapseCmfBundle(),
+ new Synapse\Admin\Bundle\SynapseAdminBundle(),
+ new Synapse\Page\Bundle\SynapsePageBundle(),
+
+ // demo
+ new Synapse\Demo\Bundle\AppBundle\SynapseDemoAppBundle(),
+ new Synapse\Demo\Bundle\ThemeBundle\SynapseDemoThemeBundle(),
+ ]
+ }
+}
+
+Here, we use the default parameters of Synapse. For further details about configurations, please read the reference configurations of each bundles :
+ +# app/config/config.yml
+
+# Synapse Cmf Configuration
+synapse_cmf:
+ content_types:
+ Synapse\Page\Bundle\Entity\Page:
+ alias: page
+ provider: synapse.page.loader
+
+To continue, please configure the database access for Synapse.
+The minimum configuration is the following :
+# app/config/config.yml
+
+# Doctrine Configuration
+doctrine:
+ dbal:
+ connections:
+ default:
+ # your project default connection here
+ synapse:
+ driver: pdo_mysql
+ host: "%database_host%"
+ port: "%database_port%"
+ dbname: "%database_name%"
+ user: "%database_user%"
+ password: "%database_password%"
+ charset: UTF8
+ orm:
+ auto_generate_proxy_classes: "%kernel.debug%"
+ default_entity_manager: default
+ entity_managers:
+ synapse: ~
+ default:
+ # your project default em configuration
+
+Synapse Cmf uses a dedicated entity manager, for more flexibility. For furthers details, please read the configuration of CmfBundle.
+The other dependendies MajoraFrameworkExtraBundle et StofDoctrineExtensionsBundle are directly configured by default in CmfBundle.
+Add the Synapse Cmf routing to your project so you can access to administration modules and frontpages.
+# app/config/routing.yml
+
+# Front
+synapse_page_content:
+ resource: "@SynapsePageBundle/Resources/config/routing/content_type.yml"
+ prefix: /{_locale}
+ defaults: { _locale: %locale% }
+ requirements: { _locale: fr|en }
+ options:
+ synapse_theme: bootstrap
+
+# Admin
+synapse_admin:
+ resource: "@SynapsePageBundle/Resources/config/routing/admin.yml"
+ prefix: "/synapse/admin/page"
+ options:
+ synapse_theme: bootstrap # theme actif du projet (voir configuration des thèmes)
+
+Lastly, please test the installation with the following commands :
+php bin/console debug:container | grep synapse
+php bin/console debug:router | grep synapse
+
+Once the the configuration is operational, build the database with the following commands :
+# It creates the database if none exists
+php bin/console doctrine:database:create --connection=synapse --if-not-exists
+# Table building
+php bin/console doctrine:schema:update --force --em=synapse
+
+Then, install assets and clear the cache :
+php bin/console assets:install
+php bin/console cache:clear
+
+The meda librady of Synapse Cmf uses the directory web/assets to store uploaded media files (the path is configurable). In general, we don't want to put these file in our version control system (eg. Git). So add this directory to your .gitignore.
#.gitignore
+web/assets
+Synapse Cmf is now operational in its simplest version, the power is yours to build your pages with the administration interface, available here http://your.env.dev/app_dev.php/synapse/admin/page (for default configuration).
+Please take note that the used theme is the demo theme, a simple theme built with Boostrap 3. It contains only one template, only one content type (the "page"), and only one built-in component. +In order to create your own content types, templates and components, please read the dedicated sections.
+ + +The complete edition allows to quickly reach a fonctional result. But sometimes, it is necessary to optimize the loaded code, or simply don't need all the features.
+To stay in the logic of providing the maximum to a project, without overload it, Synapse Cmf dispose of three additional distributions, each of theme containing a kernel of the Synapse Cmf (and its dependencies). +The choice is yours to pick the one you need, depending of the need of your project.
+| Distribution | +Package composer | +Features | +Type de projet | +Configuration | +
|---|---|---|---|---|
| SynapseCmfBundle | +"synapse-cmf/synapse-cmf-bundle": "~1.0" |
+Rendering engine, media librady module, programatic API | +Project without backoffice, where extern interfaces are not necessarily screens (CQRSarchitectures, web services, ...) | +See | +
| SynapseAdminBundle | +"synapse-cmf/synapse-admin-bundle": "~1.0" |
+Includes SynapseCmfBundle, add a html interface of element management of Synapse (skeletons, media library) and the default backoffice theme | +typic project fo "interface management", when some other screens will be implemented, and the contents decorated by editorialists. | +See | +
| SynapsePageBundle | +"synapse-cmf/synapse-page-bundle": "~1.0" |
+Includes SynapseAdminBundle, add a content type "Page", which represent a simple web page, manage the referencing and the tree. Also it adds one screen to the backoffice, providing creation/edition of pages. | +Distribution dedicated to showcase sites or simple sites, in the purpose of evolutivity to expose other data. | +See | +
This distribution contains the minimum requirements to work with Synapse. It is actually used when there is an existing backoffice, or when adjacent business modules set a graphic chart or an incompatible markup with the native adminsitration.
+It contains :
+The installation works with Composer, as many Symfony bundles do :
+composer require synapse-cmf/synapse-cmf-bundle ~1.0
+
+This bundle requires other packages of the community in additional of the Symfony standard edition's packages :
+// app/AppKernel.php
+
+class AppKernel extends Kernel
+{
+ public function registerBundles()
+ {
+ $bundles = [
+ // ...
+ new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
+ new Majora\Bundle\FrameworkExtraBundle\MajoraFrameworkExtraBundle($this),
+ new Synapse\Cmf\Bundle\SynapseCmfBundle(),
+ ]
+ }
+}
+
+Furthermore, some of them need to me configured so that Synapse can use them, (eg. Doctrine) :
+# app/config/config.yml
+
+# Synapse Cmf Configuration
+synapse_cmf:
+ content_types:
+ Content\Type\Entity\Full\Qualified\Class\Name:
+ alias: content_type # content type alias into Cmf Admin and configurations
+ loader: content_type.provider.id # service id of a service which can load this content type
+ // ...
+ components:
+ social_sharing: # component name
+ form: Acme\Bundle\AppBundle\Form\Component\SocialSharingType.php # component data form type
+ controller: AcmeAppBundle:SocialSharingComponent:render # component rendering controller
+ template_path: "AcmeAppBundle:Demo:social_sharing.html.twig" # component default template
+ // ...
+ media:
+ store:
+ physical_path: %kernel.root_dir%/../../web/assets # define where store all files uploaded through media manager
+ web_path: assets # path to media storage, after web root
+ forms:
+ enabled: true # you can disable Synapse form extension if you don't use them into your own content type forms
+
+# Doctrine Configuration
+doctrine:
+ dbal:
+ connections:
+ default:
+ # default connection here
+ synapse:
+ driver: pdo_mysql
+ host: "%database_host%"
+ port: "%database_port%"
+ dbname: "%database_name%"
+ user: "%database_user%"
+ password: "%database_password%"
+ charset: UTF8
+ orm:
+ auto_generate_proxy_classes: "%kernel.debug%"
+ default_entity_manager: default
+ entity_managers:
+ synapse: ~
+ default:
+ # default em configuration
+
+About these configurations :
+php bin/console doc:sch:update --em=synapse or php bin/console doctrine:migrations:diff --filter-expression="/^synapse_.+/" --em=synapse via the migrationsAbout MajoraFrameworkExtraBundle : this dependency contains classes and utilitary services in extension of Symfony.
+Synapse Cmf is also compatible with DoctrineMigrationsBundle, useful during deployments of further project updates.
+ + +This distribution adds an administration interface to the basic distribution. +It can be used as a base to build a backoffice for the project.
+Added features :
+Warning : this distribution requires CmfBundle, which must be initialised and configured, as described prefiously.
+The installation works with Composer (synapse-cmf-bundle is included) :
composer require synapse-cmf/synapse-admin-bundle ~1.0
+
+Please reference the bundle in you application kernel :
+<?php
+// app/AppKernel.php
+
+public function registerBundles()
+{
+ $bundles = array(
+ // ...
+ new Synapse\Admin\Bundle\SynapseAdminBundle(),
+ );
+}
+
+# app/config/config.yml
+
+# Synapse Admin Configuration
+synapse_admin:
+ base_layout: 'SynapseAdminBundle::base.html.twig' # base template to use for all Synapse admin Twig templates (use extends keywords, see the template to guess all used blocks)
+
+# app/config/routing.yml
+
+# Synapse Admin
+synapse_cmf_admin:
+ resource: "@SynapseAdminBundle/Resources/config/routing.yml"
+
+
+
+ This distribution adds a content type named "Page", and also its administration interface to the AdminBundle distribution.
+The content type "Page" represent a simple web page, with the HTML metadata management, a mechanical of puslish/archiving and an tree management.
+The administration interface of pages includes also the form of the Synapse theme.
+This distribution is perfect to start to use Synapse Cmf. It offers a simple use case of the framework. It can be useful for unique page of a website too, like homepage, landing pages, search results, and/or as base for other complex features, like a cart, a user account etc.
+Warning : this distribution requires CmfBundle and AdminBundle.
+The installation works with Composer, and includes both synapse-cmf-bundle and synapse-cmf/synapse-admin-bundle :
composer require synapse-cmf/synapse-page-bundle ~1.0
+
+Please reference the bundler in your application kernel :
+<?php
+// app/AppKernel.php
+
+public function registerBundles()
+{
+ $bundles = array(
+ // ...
+ new Synapse\Page\Bundle\SynapsePageBundle(),
+ );
+}
+
+# app/config/config.yml
+
+# Synapse Cmf Configuration
+synapse_cmf:
+ content_types:
+ Synapse\Page\Bundle\Entity\Page: # you have to manually reference page content type into Cmf configuration
+ alias: page
+ provider: synapse.page.loader
+
+# Synapse Page Configuration
+synapse_page:
+ rendering_route: synapse_content_type_page # page rendering route, used into admin to generate frontend links
+
+# app/config/routing.yml
+
+# Front
+synapse_page_content:
+ resource: "@SynapsePageBundle/Resources/config/routing/content_type.yml"
+ options:
+ synapse_theme: bootstrap
+
+# Admin
+synapse_admin:
+ resource: "@SynapsePageBundle/Resources/config/routing/admin.yml"
+ prefix: "/synapse/admin/page"
+ options:
+ synapse_theme: bootstrap
+
+Note : you don't need to include the AdminBundle routing, PageBundle already do it.
+ + +The content types are an abstraction of each business objects (or entities) of the project using Synapse.
+These content types are decorated by the engine with a template. They are not directly modified, they are a simple view created from an object.
+The reference of a content type is global to the whole application, via the CmfBundle configuration :
+# app/config/config.yml
+
+synapse_cmf:
+ content_types:
+ Synapse\Page\Bundle\Entity\Page: # Synapse built-in page content type
+ alias: page
+ provider: synapse.page.loader
+ Acme\Bundle\AppBundle\Entity\News: # Custom content type
+ alias: news
+ provider: acme.news.repository
+
+The declared entity class must implement the interface ContentInterface :
+// src/Acme/Bundle/AppBundle/Entity/News.php
+
+use Synapse\Cmf\Framework\Theme\Content\Model\ContentInterface;
+
+class News implements ContentInterface
+{
+ protected $id;
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * @see ContentInterface::getContentId()
+ */
+ public function getContentId()
+ {
+ return $this->getId();
+ }
+}
+
+Please take note that the Doctrine repository must implement an interface too to be referenced :
+// src/Acme/Bundle/AppBundle/Repository/NewsOrmRepository.php
+
+use Doctrine\ORM\EntityRepository;
+use Synapse\Cmf\Framework\Theme\Content\Provider\ContentProviderInterface;
+
+class NewsRepository extends EntityRepository implements ContentProviderInterface
+{
+ // ....
+
+ /**
+ * @see ContentProviderInterface::retrieveContent()
+ */
+ public function retrieveContent($contentId)
+ {
+ return $this->find($contentId);
+ }
+}
+
+And... It's all, Synapse is now capable of decorating your object News, thanks to a theme.
+ + +The decoration elements o the content types are declared within the theme. +These themes are true namespaces where each element and each configuration are partitioned.
+Over the technical aspect, they are a way to easily change the graphic theme of the whole application.
+A theme is created from a Symfony bundle. +The benefit of this consist in activing and sharing Synapse themes as well as bundles, and gathering all resource types inside : templates, configurations, routes, assets...
+Let's start from a brand new bundle, via the command php bin/console generate:bundle.
In the bundle class, use the Synapse inheritance instead of the Symfony inheritance :
+// src/Acme/Bundle/DemoThemeBundle/AcmeDemoThemeBundle.php
+
+use Synapse\Cmf\Bundle\Distribution\Theme\Bundle\Bundle as SynapseThemeBundle;
+
+class AcmeDemoThemeBundle extends SynapseThemeBundle
+{
+}
+
+This inheritance provides additional configurations, particularly a configuration file allowing an easy theme configuration.
+This configuration file goes in the directory Resources/config of your bundle :
# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+
+synapse:
+ acme_demo: # your theme name
+ structure: # all theme structure will be defined here (templates, zones, components)
+ home: # template name
+ menu: # zone name
+ menu: ~ # allowed component in this zone
+ body:
+ text: ~
+ gallery: ~
+ news_list: ~
+ landing:
+ menu:
+ menu: ~
+ body:
+ news_list: ~
+ sidebar:
+ news_list: ~
+ news:
+ menu:
+ menu: ~
+ body:
+ news_body: ~
+ sidebar:
+ news_list: ~
+
+The literal translation of a part of the former configuration is :
+The theme structure "acme_demo" is constituted with 3 tremplates :
+ - home : two zones,
+ - menu, allowing only the component "menu"
+ - body, allowing components : "text", "gallery" and "news_list"
+ - landing : three zones,
+ - menu, allowing only the component "menu"
+ - body, allowing only the component "news_list"
+ - sidebar, allowing only the component "news_list"
+ etc...
+We will come back in detail on the template/zone/component setting later. The important here is to notice taht one theme is defined only by its name and its structure.
+Please note that the file synapse.yml is the core of the prototype pattern of Synapse.
Lastly, don't forget to activate the bundle in your application Kernel.
+Synapse can use only one theme at once, and have to be initialized with this theme.
+Many options are available, the most simple is via the routing of your front and admnin controlers :
+# app/config/routing.yml
+
+# Synapse Admin
+synapse_admin:
+ resource: "@SynapsePageBundle/Resources/config/routing/admin.yml"
+ prefix: "/synapse/admin/page"
+ options:
+ synapse_theme: acme_demo # Theme to activate
+
+# Acme front
+acme_front :
+ resource: "@AcmeAppBundle/Resources/config/routing/front.yml"
+ options:
+ synapse_theme: acme_demo
+
+# Synapse Page
+synapse_page_content:
+ resource: "@SynapsePageBundle/Resources/config/routing/content_type.yml"
+ options:
+ synapse_theme: acme_demo
+
+The admin of Synapse requires the theme too in way to know which theme he has to edit to activate some lazy loaded configurations. +L'admin de Synapse a également besoin du thème qu'il doit éditer, pour activer certaines configurations "lazy-loadées".
+More options are available to manage more specificaly the theme activation, see the article of the dedicated cookbook (wip).
+ + +Templates are the core of the decoration of a content type. They are the one which define styles, positions, layouts and shown informations. As well as any Symfony application.
+Physically, templates are Twig files, the native templating engine included in Symfony. Templates take advantage of library extensions to add options, particularly the zone include.
+These zones are areas where components can be added. They are called from Twig tags, and defined in the theme prototype.
+To start, here is the twig file initialization for our first template :
+<!-- src/Acme/Bundle/DemoThemeBundle/Resources/views/homepage.html.twig -->
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Acme Demo</title>
+ <link rel="stylesheet" href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css">
+</head>
+<body>
+ {% block main_nav %}
+ <nav class="main_nav">{{ synapse_zone('menu') }}</nav>
+ {% endblock %}
+ {% block content %}
+ <div class="container">
+ {% block main_content %}
+ <section class="main">{{ synapse_zone('body') }}</section>
+ {% endblock %}
+ {% block sidebar %}
+ <aside>{{ synapse_zone('sidebar') }}</aside>
+ {% endblock %}
+ </div>
+ {% endblock %}
+ <footer>Acme Demo powered by SynapseCmf</footer>
+</body>
+</html>
+
+You can customize the HTML structure to fit to your need.
+Then, in the theme prototype, the template must be referenced in Synapse, and added to the theme.
+# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+synapse:
+ acme_demo:
+ structure:
+ home: # Add the template alias to the theme structure
+ # ...
+ templates:
+ home: # Definition of the template alias in Synapse
+ path: "AcmeDemoThemeBundle::homepage.html.twig" # Physical path of the Twig template
+ # ...
+
+As previously explained, Synapse templates are built with zones. These zones are called from the Twig file of the template with the tag {{ synapse_zone('zone_name', { hello: 'world' }) }}. They must be declared in the file synapse.yml too.
+The zone configuration of the twig file aboce would be :
# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+synapse:
+ acme_demo:
+ structure:
+ home:
+ menu: ~
+ body: ~
+ sidebar: ~
+ # ...
+ # ...
+ zones:
+ menu: ~
+ body: ~
+ sidebar: ~
+
+The namespace "synapse.acme_demo.zones" state the theme zones and their configuration (see the reference (wip) du fichier synapse.yml), and are linked to templates within theme structure prototype.
+After the setting, it is time to test. +The creation of a HTTP response with Synapse takes place in the Controller. +Let's create a controller in order to render the content PAge in the template "home".
+// src/Acme/Bundle/AppBundle/Controller/PageController.php
+
+class PageController extends Controller
+{
+ // ...
+
+ public function renderAction($path, Request $request)
+ {
+ if (!$page = $this->get('acme.news.repository')->retrieveByPath($path)) {
+ throw new NotFoundHttpException(sprintf('No online page found at path "%s".',
+ $path
+ ));
+ }
+
+ return $this->get('synapse') // get Synapse engine
+ ->createDecorator($page, 'home') // create a decorator for $page content into "home" template
+ ->decorate(array('page' => $page) // render template with $page parameter (like render() method with Twig)
+ ;
+ }
+}
+
+The rendering of a content in a template has two steps : first of all, we instantiate in a Decorator the theme prototype for the content with the template name as a paremeter. Then we resolve the Decorator in order to generate a HTTP response. +Le rendu d'un contenu dans un template se passe en deux étapes : d'abord on instancie le prototype du thème pour le contenu et le template en paramètre dans un objet Decorator; puis on résout ce Decorator pour générer une réponse HTTP.
+Note : it is possible to resolve a template rendering under a string form via the method render(), to decorate email, generate pdf...
Then, a route is required to display the generated response :
+# src/Acme/Bundle/DemoThemeBundle/Resources/config/routing.yml
+
+# Page content type
+acme_page_render:
+ path: "/{path}.{_format}"
+ defaults:
+ _controller: "AcmeAppBundle:Page:render"
+ _format: html
+ requirements:
+ path: "[^.]*"
+
+Please notice that the code above is a specific implementation for the native content type Page. The implementation of this content type may vary in your own content types, as well as it is possible to call a page in a different way. Fore example, you can use the identifier.
+Last step : create a Page object. For this purpose, you can use the interface included in the SynapseBundle, available at this address : /synapse/admin/page/create (if you kept the default settings).
From now, your page is visible at the chosen url, decorated with the created template.
+ + +The themes / templates / zones are the interface layer between the content (your business object) and the decoration. They are like a uniform with multiple slots for medals. It's up to you to decorate your uniform with your medals.
+In Synaps Cmf, these medals are the components.
+In each zone of each template, you can add some components. Each component can be rendered in any zone, from a backend point of view.
+From a frontend point of view, it is obvious that a component "menu" can't be rendered like a top bar or a footer. This rendering management is defined in synapse.yml of the active theme.
The basic version of Synapse Cmf (SynapseCmfBundle) includes 5 components :
+These components must be activated in zones to be added. LEt's take a simple example from the example theme :
+# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+synapse:
+ acme_demo:
+ structure:
+ home:
+ menu:
+ menu: ~
+ body:
+ text: ~
+ gallery: ~
+ sidebar:
+ static: ~
+ free: ~
+ # ...
+
+This configuration activate built-in components in the dedicated zones, rendered in Twig files, defined by default. +The prototypung is finished. Only remains the inclusion of compoenents in the template zones. +The prototyping is finished, now we need to include some components in template zones. Everything is managed from the administration interface. For example, in you Page edition form:
+Inside each theme, Synapse use the default rendering of ntavie components. Obviously, you can custom the rendering by this way :
+# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+synapse:
+ acme_demo:
+ structure :
+ # ...
+
+ # ...
+
+ components:
+ menu:
+ path: "AcmeDemoBundle:Demo:menu.html.twig"
+ text:
+ path: "AcmeDemoBundle:Demo:text.html.twig"
+ gallery
+ path: "AcmeDemoBundle:Demo:gallery.html.twig"
+ static:
+ config:
+ templates:
+ contact: "AcmeDemoBundle:Demo:contact_widget.html.twig"
+ advertising: "AcmeDemoBundle:Demo:advertising.html.twig"
+ free: ~
+
+Note : Twig files of a component rendering can be achritectured and named as your wish, no black magic here.
+Note 2 : all the components have a "config" key, not only the "static" components. (see the reference of native component configuration (wip)).
+Override each configuration and create as many twig file as you want to customize your rendering.
+By the way, Synapse would not be a framework if it was not possible to create your own components to answer to your specific needs.
+Create your own comopnent is simple. Synapse requires nothing but 3 configuration files.
+For the further examples, we will create a component which can display the last news, reading in a Doctrine Orm mapped database.
+Each component is declared in the CmfBundle configuration :
+# app/config/config.yml
+
+# ...
+synapse_cmf:
+ # ...
+ components:
+ news_list:
+ controller: "AcmeAppBundle:News:listComponent" # specific Symfony style controller reference
+ form: Acme\Bundle\AppBundle\Form\Type\NewsListComponentType # form type FQCN
+ template_path: "AcmeAppBundle:Demo:news_list.html.twig" # default template Symfony style reference
+ # ...
+
+Then, it must be activated in the themes as a native component :
+# src/Acme/Bundle/DemoThemeBundle/Resources/config/synapse.yml
+synapse:
+ acme_demo:
+ structure :
+ home:
+ body:
+ news_list: ~
+ # ...
+
+Then, you need to create 3 files declared in the configurations : the controller, the form and the default Twig file.
+Synapse creates a nested form tree to let a quick and compelte settting of the whole structure of a template. +This tree dynamically includes the custom forms required to manage your component data.
+In the case of the news list, the final user of the backoffice would add contents, and configure the components, for example. He requires the options :
+To support this data customization of a component, Synapse requires a definition of a form type (a Symfony notion for the definition of the form elements) for each componenent.
+// src/Acme/Bundle/AppBundle/Form/Type/NewsListType.php
+
+namespace Motion\Bundle\AdminBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\IntegerType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Validator\Constraints\GreaterThan;
+use Synapse\Cmf\Bundle\Form\Type\Framework\Component\DataType;
+
+class NewsListComponentType extends AbstractType
+{
+ public function getParent()
+ {
+ return DataType::class;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $builder
+ ->add('title', TextType::class, array())
+ ->add('read_more_label', TextType::class, array())
+ ->add('nb_displayed_news', IntegerType::class, array(
+ 'constraints' => array(new GreaterThan(array('value' => 0))),
+ ))
+ ;
+ }
+}
+
+All these values matching the form fields are saved with the component, in a variable named data. Then, it is possible to fetch these data via the method $component->getData(), or only one data with the key and a default value via $component->getData('nb_displayed_news', 5).
The componenents are called via the Symfony sub-requests, the component controllers look like classic controllers, with some additions:
+// src/Acme/Bundle/AppBundle/Controller/NewsController.php
+
+namespace Acme\Bundle\AppBundle\Controller;
+
+use Synapse\Cmf\Framework\Theme\Component\Model\ComponentInterface;
+// ...
+
+class NewsController extends Controller
+{
+ // ...
+
+ public function listComponentAction(ComponentInterface $component)
+ {
+ return $this->container->get('synapse')
+ ->createDecorator($component)
+ ->decorate(array(
+ 'last_news' => $this->container->get('doctrine')
+ ->getRepository(News::class)
+ ->createQueryBuilder('news')
+ ->orderBy('news.date', 'desc')
+ ->getQuery()
+ ->setMaxResults($component->getData('nb_displayed_news', 5))
+ ->getResult()
+ ))
+ ;
+ }
+}
+
+In the above example of a controller, we add a list of objects News to the data, from the database via Doctrine, limited by the number of news to display, and defined by the form given in the data of the component, by default 5.
+Once the component is defined, it remains to skin it.
+To do that, proceed like any Twig templates included with {{ include() }}. Define only the HTML structure, regardless the inheritance.
<section class="news_list_component">
+ <h2 class="separator">{{ title }}</h2>
+ <div class="news_wrapper">
+ {% for news in last_news %}
+ <article>
+ <h3>
+ {{ news.title|capitalize }}
+ <span class="lower">{{ news.date|date('d/m/Y') }}</span>
+ </h3>
+ <p>{{ news.headline }}</p>
+ {% if news.body is not empty %}
+ <button href="{{ path('acme_news_render', { id: news.id }) }}">
+ {{ read_more_label }}
+ </button>
+ {% endif %}
+ </article>
+ {% endfor %}
+ </div>
+</section>
+
+Some tips:
+decorate() of the Synapse decoratorapp of Symfony, you can access to the standard Twig options and your possible additionsThat's it, you now know how to use the main features of Synapse Cmf ! +Many features, configurations and models of implementation was not presented, but the purpose was elsewhere : help you to start a synapse project by fastly displaying a screen.
+All the non detailed components will be developed in the Cookbook in the course of writing. Do not hesitate to come back later !
+Thank you for reading, we hope that Synapse can fill your technical needs the most advanced !
+ + +{{ news.headline }}
+ {% if news.body is not empty %} + + {% endif %} +The main 5 notions to start a decoration of a content are the following :
+These elements are typed. These types are created from the theme configuration and the theme prototyping. They provide information concerning the template rendering, like the Twig template to call, the default configuration, the allowed components for a zone, image format etc.
+The prototyping of these elements allows a big flexibility of the model and the rendering engine of Synapse, without writing a php line : the front-end developers can take back their right on the setting of their rendering, and controle the whole process of content decoration.
+For the following examples of this documentation, we will use the following objects :
+We consider that the database managed by Doctrine is initialized to manage the News objects.
+ + +Now that you created your first project with Synapse Cmf standard edition, let's detail what are the possibilities of extension and customisation to keep your content management system as clase as possible to the business of your customer.
+Table of contents :
+ + + +Synapse tries to be the less intrusive and the as decoupled as possible. It is the same for any data, which have not to create conflict with the database of your business project.
+So, We adise you to create a separate database for Synapse. All Synapse needs is a SQL Doctrine compatible database.
+Here is an example of configuration to define an independent database for Synapse :
+# app/config/config.yml
+
+# Doctrine Configuration
+doctrine:
+ dbal:
+ connections:
+ default:
+ # default connection here
+ synapse:
+ driver: "%synapse_database_driver%"
+ host: "%synapse_database_host%"
+ port: "%synapse_database_port%"
+ dbname: "%synapse_database_name%"
+ user: "%synapse_database_user%"
+ password: "%synapse_database_password%"
+ charset: UTF8
+ orm:
+ auto_generate_proxy_classes: "%kernel.debug%"
+ default_entity_manager: default
+ entity_managers:
+ synapse: ~
+ default:
+ # default em configuration
+
+# app/config/parameters.yml
+parameters:
+ # ...
+ synapse_database_driver: pdo_mysql
+ synapse_database_host: your_host
+ synapse_database_port: your_port
+ synapse_database_name: synapse
+ synapse_database_user: your_user
+ synapse_database_password: your_password
+
+How it works ? To be continued... (wip)
+ + +This document aims to familiarize you with ll the Synapse components, from the installation to the daily use, from the simple to the complex cases, passing by its configuration.
The project Synapse-cmf will follow the semver, like all the dependent projects. +For more simplicity, each version of the project synapse-cmf/synapse-cmf will be a new release of each side project.
+Stabilization and standardization version +Version de stabilisation et standardisation.
+First evolution release
+Cette distribution contient le strict minimum pour travailler avec Synapse; c'est en général celle que l'on va utiliser quand on dispose déjà de son back-office, où lorsque les modules métiers adjacents imposent une charte graphique ou un markup incompatible avec l'administration native.
+Cette distribution contient le strict minimum pour travailler avec Synapse; c'est en général celle que l'on va utiliser quand on dispose déjà de son back-office, ou lorsque les modules métiers adjacents imposent une charte graphique ou un markup incompatible avec l'administration native.
Elle contient :
{{ news.headline }}
+ {% if news.body is not empty %} + + {% endif %} +