Coder Social home page Coder Social logo

orbitale / cmsbundle Goto Github PK

View Code? Open in Web Editor NEW
60.0 7.0 14.0 382 KB

Super-lightweight CMS bundle for Symfony

Home Page: https://demo.orbitale.io/orbitale_cms/

License: MIT License

PHP 93.45% Twig 6.55%
php cms symfony symfony-bundle cms-bundle hacktoberfest

cmsbundle's Introduction

SensioLabsInsight Coverage Status Build Status Scrutinizer Code Quality

⚠️ You're looking at the 4.x branch documentation.
If you need information about 3.x, go here If you need information about 2.x, go here If you need information about 1.x, go here

Index

Orbitale CMS Bundle

This bundle is a simple helper to create a very simple CMS based on a classic system with Pages and Categories.

Requirements

  • PHP 7.0+
  • Symfony 3.0+
  • Doctrine ORM

Install

Require the bundle by using Composer:

$ composer require orbitale/cms-bundle

Setup

Register the necessary bundles in your Kernel:

<?php
// app/AppKernel.php
public function registerBundles()
{
    $bundles = [
        // ...
        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, make sure that OrbitaleCmsBundle routes are loaded at the end of your routing file, or you may have some unexpected "404" or other errors, depending on the routes priority.
This is why we recommend you to load the CategoryController before the PageController, and let both routes config be the last ones of your routing.yml file.
Note: In technical terms, the whole URI is scanned, not a simple part of it, this is why it can analyze very deep URIs like /home/blog/parent-link/child-link/element, and check all pages/categories.

Example:

# app/config/routing.yml
orbitale_cms_category:
    resource: "@OrbitaleCmsBundle/Resources/config/routing/categories.yaml"
    prefix:   /category/

orbitale_cms_page:
    resource: "@OrbitaleCmsBundle/Resources/config/routing/pages.yaml"
    prefix:   /page/

Create your entities

This bundle supports Doctrine ORM only.

In order to use it, you must create your own entities and configure the bundle with them.

Update your config:

# app/config/config.yml
orbitale_cms:
    page_class: AppBundle\Entity\Page
    category_class: AppBundle\Entity\Category

Create the Page entity and add it to your config

<?php

namespace AppBundle\Entity;

use Orbitale\Bundle\CmsBundle\Entity\Page as BasePage;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Orbitale\Bundle\CmsBundle\Repository\PageRepository")
 * @ORM\Table(name="orbitale_cms_pages")
 */
class Page extends BasePage
{
    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

Create the Category entity and add it to your config

<?php

namespace AppBundle\Entity;

use Orbitale\Bundle\CmsBundle\Entity\Category as BaseCategory;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Orbitale\Bundle\CmsBundle\Repository\CategoryRepository")
 * @ORM\Table(name="orbitale_cms_categories")
 */
class Category extends BaseCategory
{
    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

Update your db schema

Update your database by executing this command from your Symfony root directory:

$ php app/console doctrine:schema:update --force

Usage

Manage pages

To manage your pages, you should use any back-end solution, like EasyAdmin (which we suggest) or SonataAdmin, or any other backend solution that can operate CRUD actions on entities. You must have configured it to manage at least the Orbitale\Bundle\CmsBundle\Entity\Page entity.

View pages

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 are 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 rules for your routing, unless you may have many "404" errors.

Generate a route based on a single page

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', ['slugs' => $page->getTree()]);
    // $url === /welcome/our-company/team

With this, you have a functional tree system for your CMS!

Change homepage

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.

You can have multiple homepages if you add them restrictions based on host and locale (see next chapter).

Page restriction based host and/or locale

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/

Design

OrbitaleCmsBundle has some options to customize the design of your simple CMS.

Mostly, you will take care of the layouts option (see next chapter), or the design option.

Using different layouts

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.

Advanced layout configuration

The basic configuration for a layout is to specify a template to extend.

But if you look at the Configuration reference you will see that there are many other parameters you can use to define a layout:

Prototype of a layout configuration:

  • 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 (if you need it).
  • 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 Twig asset() function. The CSS is rendered in the stylesheets block, and js in the javascripts block.
  • host:
    The exact domain name you want the layout to match with.
  • pattern:
    The regexp of the path you want to match with for this layout. It's nice if you want to use a different layout for categories and pages. For example, you can specify a layout for the ^/page/ pattern, and another for ^/category/. If you specify a very deep pattern, you can even change the layout for a single page!

Take another look on the config reference if you need to get the prototype defaults.

⚠️ Warning! The first matching layout will be used, as well as routing would do, so be sure to configure them in the right order!
Empty values won't be taken in account.

Changing the "breadcrumbs" look

Under the design option, you have some that you can use to optimize the rendering of the breadcrumbs.

Basically, it will look like this:

Homepage > Parent page > Current page

Note: The breadcrumbs wrapper already has id="breadcrumbs" on its tag.

  • breadcrumbs_class:
    Changes the class of the breadcrumbs wrapper.
  • breadcrumbs_link_class:
    Changes the class of any link in the breadcrumbs.
  • breadcrumbs_current_class:
    Changes the class of the current page in the breadcrumbs (which is not a link).
  • breadcrumbs_separator (default: ">"):
    Changes the default separator used. You can use anything, but mostly we see >, /, | or * on the web.
    Note: This character is escaped in twig, so do not use things like &larr; or the & sign will be replaced with &amp; (as well as other characters).
  • breadcrumbs_separator_class:
    You can specify a class for the separator (which is wrapped by a <span> tag), if you want to use special design or interaction on it.

Cache

If you want to cache your cms results, just activate it via the config:

    cache:
        enabled: true
        ttl: 300

It uses Doctrine Result Cache so you need to activate it:

    doctrine:
        orm:
            result_cache_driver: apcu

You can read more about DoctrineCache here.

Setup EasyAdminBundle to manage pages and categories in its back-end

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: admin.cms.pages
            class: App\Entity\Page
            show:
                fields: [ id, parent, title, slug, tree, content, metaDescription, metaTitle, category, host, locale, homepage, enabled ]
            list:
                fields: [ id, parent, title, slug, tree, host, locale, { property: homepage, type: boolean }, { property: enabled, type: boolean } ]
            form:
                fields: [ title, slug, content, metaDescription, metaTitle, metaKeywords, css, js, category, parent, host, homepage, enabled ]

        Categories:
            label: "Cms Categories"
            class: App\Entity\Category
            show:
                fields: [ id, parent, title, slug, tree, content, host, locale, homepage, enabled ]
            list:
                fields: [ id, parent, name, slug, description, { property: enabled, type: boolean } ]
            form:
                fields: [ name, slug, description, parent, enabled ]

Configuration reference

# app/config/config.yml
orbitale_cms:
    page_class: ~              # Required, must extend Orbitale Page class
    category_class: ~          # Required, must extend Orbitale Category class
    layouts:
        # Prototype
        name:
            name:       ~      # Optional, it's automatically set from the key if it's a string
            resource:   ~      # Required, must be a valid twig template
            assets_css: []     # Injected with the `asset()` twig function
            assets_js:  []     # Injected with the `asset()` twig function
            pattern:    ~      # Regexp
            host:       ~      # Exact value
    design:
        breadcrumbs_class:           "breadcrumb"  # The default value automatically suits to Bootstrap
        breadcrumbs_link_class:      ""
        breadcrumbs_current_class:   ""
        breadcrumbs_separator:       ">"
        breadcrumbs_separator_class: "breadcrumb-separator"
    cache:
        enabled: false
        ttl: 300

Changelog

Go to the releases page to see what are the changes between each new version of Orbitale CmsBundle!

cmsbundle's People

Contributors

aimproxy avatar marcosrjjunior avatar orbitaleio avatar pierstoval avatar scrutinizer-auto-fixer avatar sfarkas1988 avatar trekels avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmsbundle's Issues

use php8 attribute for ORM ?

Hello,

Do you plan to update the project with php8 Attribute for the entity (doctrine?)

It will be more easy to extand Page for example like this:


namespace App\Entity;

use Doctrine\DBAL\Types\Types;
use Orbitale\Bundle\CmsBundle\Entity\Page as BasePage;
use Doctrine\ORM\Mapping as ORM;
use Orbitale\Bundle\CmsBundle\Repository\PageRepository;

#[ORM\Entity(repositoryClass: PageRepository::class)]
#[ORM\Table(name: 'cms_pages')]
class Page extends BasePage
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: Types::INTEGER)]
    protected int $id;


    public function getId(): int
    {
        return $this->id;
    }
}

Symfony 4.x deprecations

Guys, I resolved some more deprecation here https://github.com/Orbitale/CmsBundle/pull/18/files but that would require Symfony 4. Not sure if I should force Symfony 4.2 in composer.json.

There is still some more deprecation that I struggle to fix because it requires bigger changes:
User Deprecated: Loading Twig templates from the "/Users/maciej.wagner/PhpstormProjects/CmsBundle/Tests/Fixtures/App/Resources/views" directory is deprecated since Symfony 4.2, use "/Users/maciej.wagner/PhpstormProjects/CmsBundle/templates" instead.

User Deprecated: Relying on the default value ("false") of the "twig.strict_variables" configuration option is deprecated since Symfony 4.1. You should use "%kernel.debug%" explicitly instead, which will be the new default in 5.0.

User Deprecated: Auto-injection of the container for "Orbitale\Bundle\CmsBundle\Controller\PageController" is deprecated since Symfony 4.2. Configure it as a service instead.

Can you help?

orbital demo link to admin page is incorrect

at

	http://www.orbitale.io/2015/12/28/cms-bundle.html

link

	View the demo here
	http://demo.orbitale.io/orbitale_cms/

follow to

	https://demo.orbitale.io/orbitale_cms/

	Homepage
		This page is set as homepage, but also as /{_locale}/homepage with a classic usage. Go to the admin page with the admin/admin user/password pair, and check the power of OrbitaleCmsBundle combined with EasyAdmin! 

link

	"the admin page"
	https://demo.orbitale.io/orbitale_cms/orbitale_cms/en/admin

is incorrect.

should be,

	https://demo.orbitale.io/orbitale_cms/en/admin

Add DoctrineBundle^2.0 compatibility for CmsBundle^3.1

The upgrade to doctrine/doctrine-bundle 2.0 is not exactly trivial, but I don't think it should be a major issue. (At the same time supporting ^3.0 is trivial, so you may add that as well if you manage ^2.0).

CmsBundle 4 is not out yet, and this is a pretty major hold-back in dependencies. Most notably this means anyone using CmsBundle has a forced dependency on some abandoned zendframework/* packages.

Can you please look into it? I assume that if there are any changes needed they can be backported from CmsBundle 4.

A way to use _locale as prefix for both category and page

Is there a way to use _locale as a prefix both for category and page routes?

My goal is to have SEO friendly routes for categories as I have for pages. Instead of /c/news/ it would be better if I could have it same as pages without any additions just /news.

Any ideas how could I achieve this easily? If I leave prefix: /{_locale}/c/ for both of their routing settings, it doesn't pass through to the second one and throws a 404. Any way to go around this?

PageRepository find by category

When find pages by category.

must be add ->andWhere('page.enabled = true') like:

public function findByCategory(Category $category, $order, $orderBy, $page, $limit): Paginator
    {
        $qb = $this->createQueryBuilder('page')
            ->where('page.category = :category')
            ->andWhere('page.enabled = true')
            ->orderBy('page.'.$orderBy, $order)
            ->setMaxResults($limit)
            ->setFirstResult($limit * ($page-1))
            ->setParameter('category', $category)
        ;

        return new Paginator($qb->getQuery()->useResultCache($this->cacheEnabled, $this->cacheTtl));
    }

Generate a specific page link depending of the _locale ?

Hello

I'm trying to generate a link on a custom page (not a cmspage) to point on a cmspage.

I do this :

<a href="{{ path('orbitale_cms_page', {slugs: 'my-page-slug'}) }}">{% trans %}menu.my_page{% endtrans %}</a>

it works perfectly. But. I'm creating a multi-language website. I can't figure out how to deal with the _locale.

As in the database the slug changes depending the language, currently I have to manually, make a condition, to check the current locale and take the good slug, but, obviously this is not a good way to do.

How am I supposed to deal with that? And by the way, I can't find any way to links 2 pages records of different language.

Thank you

Doctrine ResultCache

Hey, it would be great to be able to cache the doctrine results via configuration.

Working with Symfony ^5.0

The command I run: composer require orbitale/cms-bundle "4.x-dev"

The output:
Problem 1 - Installation request for orbitale/cms-bundle 4.x-dev -> satisfiable by orbitale/cms-bundle[4.x-dev]. - orbitale/cms-bundle 4.x-dev requires symfony/asset ^4.2 -> no matching package found.

In my composer.json file the symfony/asset is on the "5.0.*"

Can you help?

RuntimeException with multiple connections

in Resources/config/services.yml:20 is hardcoded connection: default.
This fails when doctrine uses multiple connections:

doctrine:
    dbal:
        connections:
            host_connection:
                # params
            sock_connection:
                # params
    orm:
        connection: %default_connection%

when run app/console cache:clear I got:

[RuntimeException]                                                                                                                                                    
The Doctrine connection "default" referenced in service "gedmo.listener.timestampable" does not exist. Available connections names: host_connection, sock_connection 

There should be some way to avoid a hardcoded connection. Maybe take it from ORM or from doctrine.dbal.default_connection parameter.

Twig deprecation to fix

Using the "Twig_Extension_GlobalsInterface" class is deprecated since Twig version 2.7, use "Twig\Extension\GlobalsInterface" instead.

Ethical question about how CmsBundle manage entities

Hi again, u have called ur entity Pages, wich can be related to Category, but there aren't an entity Posts. I think Pages are pages, she should stay alone, and the entity Posts should be related to one or more Category! Finally, the url generated in PostsController, should look like this: https://url.com/posts/year/month/day/subject.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.