Skip to content

Instantly share code, notes, and snippets.

@rtablada
Last active August 29, 2015 14:00
Show Gist options
  • Save rtablada/11067109 to your computer and use it in GitHub Desktop.
Save rtablada/11067109 to your computer and use it in GitHub Desktop.
My thoughts on a CMF

Admin Controller

The admin controller will extend the Laravel base controller and be crazy smart about things. If you return a string or view object, then it will be injected in the content of the BlockCMF admin layout. This allows you to program like a usual Laravel controller with your own internal layouts, sub-views, view composers, and everything and not having to be bothered about remembering to follow some weird API to make sure you inject your view into the layout. Just extend the AdminBaseController and go to town!

API Controllers (Advanced mutations to be implemented later)

Everyone likes browser based apps. BlockCMF should let you extend an APIBaseController and have your data serialized to match different JSON schemas such as ActiveModelSerializer, https://p.gr-assets.com/540x540/fit/hostedimages/1380238652/681527.jpg, or standard basic serialization that spits out Laravel's existing toJSON implementation.

Provides admin skeleton for application
Components are built as module
Each module has
Public routes
Admin routes
Custom settings routes
File based config
Database based settings
File structure
/
src/ (PSR-4, PSR-0)
config/
settings.json
*.php (normal laravel style config, there will be a symbolic link in the CMS to make this easier to get to)
module.json
BlockView class extends Illuminate\View
BlockView::make
First looks for related view in the current theme directory
If no view matches in the theme, then the Block's view is rendered
settings.json Schema
Array of Soft Setting Objects
title
type (string, array, number, select [drop down options])
options (only if select)
min (only if number) - defaults to 0
max (only if number) - defaults to null
default
module.json Schema
title
description
routes
public
admin
settings
(Route Object Schema)
title (used for H2, etc)
route name (used to match linkRoute)
description
icon - (optional)
arguments/segments for route
name
description
default

Elements

Elements are view composer powered partials to use in your views. Elements give developers an awesome way to render data on to the screen based on function parameters. An example for an Element would be a Navbar helper.

So in your public layout let's say that you want to include a footer nav and have the Navbar Element package installed: you'd just call BlockElement::render('nav-builder', 'footer') in your view.

Elements could be even more flexible and change data in more interesting ways, but usually are data agnostic so that they aren't tied into what would be a module.

Settings Pages

Settings Pages are simple information systems where there is only a single record to change. Settings can be defined as part of the global settings form, or they can be edited on dedicated settings pages. The settings will be stored using a configurable driver: database, file (using JSON files), or cache. These settings can be accessed around your application for use and abuse.

An example for this would be for managing features where only a small set of data are changed by the end user. This means that end users will never botch your CMS pages by accident while trying to change their address.

For instance, you will be able to run BlockSetting::get('site::address.street') and grab the street address for your site settings.

Module

A module is a set of content functionality that spans across Admin, Public, and (optionally) API walled segments (not sure what these different role/filter based areas should be called). Modules usually have multiple routes or functions that are available to the various role areas of your application.

Modules can further contain Settings Pages, Elements and you have full access to the Laravel Framework.

Role Areas

By default, there will be role areas for Public access, Admin access, and API access (both Admin and Public). These role areas are customizable and new role areas can be created using the toolset and a basic set of before and after filters that can be used for each Role Area.

For instance, if you want to make a customer area for your new SASS app, you can do so. Keep using the route helpers, and use the cool sytanx that makes route naming, dealing with filters and more really easy!

Core Packages

This is a list of Elements/Settings Pages/Modules that I can see the core team providing:

  1. Navbar Element (let's you create customized navbars using customized presenters or templates)
  2. Pages - A standard WYSIWYG editor for static pages. I may not like CMSs, but I can see the use for this feature
  3. Blog - I learned a lot from helping refactor Wardrobe, I think that we can pull in a lot of that knowledge (maybe even wrap wardobe up to be dropped in?)
  4. Twitter element - Everyone loves cached tweets from their accounts. Let's make that stupid easy
  5. Contact - Drop in contact page with drivers (admin panel notifications,
  1. Multisite? Does a single admin panel really allow you to target your audience affectively or is it better to deploy targeted applications? What would be an effective way of going about this if we need to handle multisite (traits for DB models, Schema Builders and just have a domain_id column)?
  2. What are your biggest hangups from using CMSs in the past?
  3. Do you see value in making admin pages for core modules be stateful browser applications (similar to Ghost CMS)? Is this worth the effort? Is it just something cool? While it would be cool for the entire admin area to be a stateful browser application, I wouldn't want to force multiple tech hurdles or limit what devs would want to do: if I want to build the pages module to be powered by Ember, that shouldn't stop someone from using Angular or vice versa.
  4. How would you be interested in helping out? Testing Alpha builds? Remote (or local) hackathons? Crowdfunding? Something else?
  5. JSON, YML, or PHP config? - IMO JSON sticks out more when browsing file trees, doesn't really allow unexpected code injection (PHP array configuration files), and doesn't drag us into a big tabs vs. spaces war (YML).
  6. Default admin panel layout CSS Framework - I'm leaning toward Gumby just because I've found Bootstrap to have accessibility issues, not really have semantic markup, also Gumby is really well written for extensibility and reusibility using SASS and Compass, so if we found a good asset story, this could be used to cut back on reusable assets. This does not dictate public role route asset and much of the form stuff for admin routes will be abstracted behind form helpers.
  7. Is Laravel a good building ground - I love Laravel and think that it gives enough flexibilty while allowing developer to grow into better and better OOP practices. I've always planned this to use Laravel, from the way DI and Controllers work to the wrappers for Route and Form builders.
  8. Templating language - should it support a templating language or use basic php (my preference)
  9. What else? I'm sure I've missed something... This is a huge undertaking so every thought and opinion counts!

Traditionally, CMS systems targeted the just the content creator. Unfortunatley, this made the task of developing complex data formats for systems like WordPress or Expression Engine really tough. The APIs were difficult to manage, there were limitations to how data was accessed and stored. Communication between modules was difficult at best.

Getting a working set of tools always felt like a hacked together set of keeping things from falling apart.

What this isn't

This CMF isn't aiming to be a theme haven. While the different Role Areas will be themable, "themes" will be custom rolled views that the end developer can put on top of the existing logic and APIs exposed by Modules.

What we aim to do

Working with CMSs in the past, I've run into a lot of CMSs that allowed you to modify content types (I'm talking core logic and data storage) directly from GUIs in the browser. While the occasionally would allow for quick development, it never made sense to me. As a developer, why would you go to a GUI (that isn't persisted) only to go back into a code editor to build your themes/layouts? Then when you hand the site over to a client, this low level modifications are still available (even if only with a set of login credentials that you don't give them). We aim to make it so that data modification is limited to only what the end user should be dealing with so you aren't getting a call that a content type got trashed by your clients intern that was just trying to update the address in the footer.

Easy for developers

Instead, Block CMF looks to put rapid, modular development at the forefront. Block gives a simple API with clean and concise configuration that allows you to work on your logic and have incredibly reusable code bases that makes good architecture and code design not only possible, but easy!

SMARTER Browser Assets

With traditional CMS systems: plugins, themes, and extensions were told to manage their own assets. This led to your code base having 20 different versions of jQuery and heavy, heavy page load times. Block will be powered by Bower.js and an asset manager that will take care of these duplications of page logic and keep things simple and clean. Reduce asset conflicts and reduce the resources your end-user has to pull from your server (no more 40+ script home pages just to load all of your different plugins that aren't even being used for the current page!)

Design Something AWESOME

Designers, don't think we've left you out either. Block will leverage an opt-in templating, layout, and theming system. This means that for your public routes, you can declare you can design to your heart's content while having powerful hooks into the data you really care about showing to your users.

It's a freaking TRANSFORMER!

CMS systems are notorious for requiring devs to hack at the core. In the BlockCMF configuration file, you'll be able to swap out major components to fit your needs.

Say your Admin panel should leverage a login system built on top of Authentication from remote EDL files. Just change the configuration to point to your custom implementation of the Authentication driver and keep working like nothing ever changed!

This all means that when you run composer update, your upgrade path is simple and easy. More time for 🍰 and less time running gitdiff, or worse, having your awesome code lost!

I want to build a content management framework. Let me describe what I mean by that.

My vision is that you could develop a module that would drop in to the CMF and have public features, admin features, and really any other routes you want to work with manually. Database interaction would be on top of an ORM and would use migrations for clean database interaction and database tables that aren't dictated by the CMS.

I would like for a lot of the configuration to be handled using JSON files or something similar.

On the admin side of things, there would be an authentication and authorization module that would provide a unified interface so that you do not have to write user auth everytime. Since there would be an Auth interface, developers could easily swap out the Auth provider for something a bit more custom without hurting core functionality.

From there, the admin area will have a skeleton view for modules to plug in to. The base menu system will be generated based on the installed modules definition JSON files. These would route to flexible views where anything returned from the module admin controllers would be inserted into the larger admin layout. For easier building of admin forms, views, etc, there would be some modified view helpers which would help take care of boilerplate required to build forms with validation and more. But, at the same time, the module developer will be able to go as low level as they want within the admin viewport.

Modules also would have two methods of configuration options: hard and soft. Hard config options would use a file based configuration and be more developer centric. Soft configuration options would be a bit like a unified key-value store for end-user modifications within a module (for instance a contact form module might have a mailTo configuration option).

Publicly available routes would really need to be awesome. For this, I think there are two things it needs to have out of the gate.

  1. A really smart view class - this would look for a view for the current route within the active theme, if it cannot find it, then it will use the module's default view
  2. A smart and easy to use menu system - given that modules will define their publicly available routes, then the CMF should be able to have a view helper that will go and build menus based on the defined routes (and configuration).

To be viable, I think if not at launch the CMF has to have the following modules built by the core team:

  1. Blog with comments
  2. Pages (for static pages)
  3. Contact form

There's a lot I would like after that which would help with module development:

  1. Good scaffolding tools - similar to Jeff Way's generators, but opinionated towards building things for modules
  2. A message bus between modules - I'd like to make it easy to make code with seperations of concerns. When working with CMS plugins in the past, I was absolutely angered by how coupled plugins were to each other and how they did not have a good API to interact with one another.
  3. An awesome AJAX editor - this gets into a targeted package which I would like to see available, but it would be nice to have a package that made handling an AJAX based editor (like Sir Trevor) crazy easy. Like as easy as CMF::routeSirTrevor('url', 'ModelName') where ModelName could be a Eloquent model or a receiving repository.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment