- Requirements
- Install
- Setup
- Usage
- Manage pages
- View pages
- Generate a route based on a single page
- Change homepage
- Using different layouts
- Advanced layout configuration
- Setup EasyAdminBundle to manage pages and categories in its back-end
- Changelog
This bundle is a simple helper to create a very simple CMS based on a classic system with Pages and Categories.
- PHP 5.4+ (because we are using Traits)
- Symfony 2.3+
- Doctrine ORM
Warning: This bundle uses PHP Traits, so you must have PHP 5.4+
Require the bundle by using Composer:
$ composer require orbitale/cms-bundle
Register the necessary bundles in your Kernel:
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Orbitale\Bundle\CmsBundle\OrbitaleCmsBundle(),
);
}
Import the necessary routing files.
Warning:
Both Page
and Category
controllers have to be "alone" in their routing path, because there is a "tree" routing
management. If you set the prefix as "/" or any other path you are already using, you may have some unexpected "404"
or other errors, depending on the routes priority.
# app/config/routing.yml
orbitale_cms_page:
resource: "@OrbitaleCmsBundle/Controller/PageController.php"
type: annotation
prefix: /page/
orbitale_cms_category:
resource: "@OrbitaleCmsBundle/Controller/CategoryController.php"
type: annotation
prefix: /category/
Update your database by executing this command from your Symfony root directory:
$ php app/console doctrine:schema:update --force
To manage your pages, you should use any back-end solution, like EasyAdmin
(which we suggest) or SonataAdmin, or any else.
You must have configured it to manage at least the Orbitale\Bundle\CmsBundle\Entity\Page
entity.
The PageController
handles some methods to view pages with a single indexAction()
, and the CategoryController
uses its route to show all pages within a specified Category
.
The URI for both is simply /{slug}
where slug
is the... page or category slug.
If your page or category has one parent
, then the URI is the following: /{parentSlug}/{slug}
.
You can notice that we respect the pages hierarchy in the generated url.
You can navigate through a complex list of pages or categories, as long as they're related as parent
and child
.
This allows you to have such urls like this one :
http://www.mysite.com/about/company/team/members
for instance, will show only the members
page, but its parent has
a parent, that has a parent, and so on, until you reach the "root" parent. And it's the same behavior for categories.
Note: this behavior is the precise reason why you have to use a specific prefix for your controllers routing import,
unless you may have many "404" errors.
Note: This behavior also works for categories.
If you have a Page
object in a view or in a controller, you can get the whole arborescence by using the getTree()
method, which will navigate through all parents and return a string based on a separator argument (default /
, for urls).
Let's get an example with this kind of tree:
/ - Home (root url)
├─ /welcome - Welcome page (set as "homepage", so "Home" will be the same)
│ ├─ /welcome/our-company - Our company
│ ├─ /welcome/our-company/financial - Financial
│ └─ /welcome/our-company/team - Team
└─ Contact
Imagine we want to generate the url for the "Team" page. You have this Page
object in your view/controller.
{# Page : "Team" #}
{{ path('orbitale_cms_page', {"slugs": page.tree}) }}
{# Will show : /welcome/our-company/team #}
Or in a controller:
// Page : "Team"
$url = $this->generateUrl('orbitale_cms_page', array('slugs' => $page->getTree()));
// $url === /welcome/our-company/team
With this, you have a functional tree system for your CMS!
The homepage is always the first Page
object with its homepage
attribute set to true. Be sure to have only one
element defined as homepage, or you may have unexpected results.
If you are hosting your application in a multi-domain platform, you can use the host
attribute in your page
to restrict the view only to the specified host.
It's great for example if you want to have different articles on different domains like blog.mydomain.com
and www.mydomain.com
.
If you want to restrict by locale
, you can specify the locale in the page.
The best conjointed use is with prefixed routes in the routing file:
# app/config/routing.yml
orbitale_cms_page:
resource: "@OrbitaleCmsBundle/Controller/PageController.php"
type: annotation
# Add the locale to the prefix for if the page's locale is specified and is not
# equal to request locale, the app will return a 404 error.
prefix: /{_locale}/page/
Obviously, the default layout has no style.
To change the layout, simply change the OrbitaleCmsBundle configuration to add your own layout:
# app/config/config.yml
orbitale_cms:
layouts:
front: { resource: @App/layout.html.twig } # The Twig path to your layout
Without overriding anything, you can easily change the layout for your CMS!
Take a look at the default layout to see which Twig blocks are mandatory to render correctly the pages.
Here is the global configuration reference for the layouts:
orbitale_cms:
layouts:
# One layout prototype
name:
resource: ~ # Required.
assets_css: []
assets_js: []
pattern: ^/
Explanation:
- name (attribute used as key for the layouts list):
The name of your layout. Simply for readability issues, and maybe to get it directly from the config. - resource:
The Twig template used to render all the pages (see the above section) - assets_css and assets_js:
Any asset to send to the Twigasset()
function. The CSS is rendered in thestylesheets
block, and js in thejavascripts
block. - pattern:
The regexp of the URI path you want to match for this layout. It's nice if you want to use a different layout for categories and pages. You can use it this way for this kind of behavior:
# app/config/config.yml
orbitale_cms:
layouts:
page:
resource: @App/layout_page.html.twig
pattern: ^/page/
category:
resource: @App/layout_category.html.twig
pattern: ^/category/
This configuration allows you to manage your pages and categories directly in the EasyAdminBundle way.
First, install EasyAdminBundle
, and set it up by reading its documentation (view link above).
After you installed it, you can add this configuration to inject your new classes in EasyAdmin:
# app/config/config.yml
easy_admin:
entities:
Pages:
label: "Cms Pages"
class: Orbitale\Bundle\CmsBundle\Entity\Page
show:
fields: [ id, parent, title, slug, tree, content, metaDescription, metaTitle, metaKeywords, css, js, category, host, locale, homepage, enabled ]
list:
fields: [ id, parent, title, slug, tree, content, category, homepage, host, locale, enabled ]
form:
fields: [ title, slug, content, metaDescription, metaTitle, metaKeywords, css, js, category, parent, host, locale, homepage, enabled ]
Categories:
label: "Cms Categories"
class: Orbitale\Bundle\CmsBundle\Entity\Category
list:
fields: [ id, name, slug, description, parent, enabled ]
form:
fields: [ name, slug, description, parent, enabled ]
Go to the releases page to see what are the changes between each new version of Orbitale CmsBundle!