Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new Contao backend #2697

Draft
wants to merge 41 commits into
base: 5.x
Choose a base branch
from
Draft

A new Contao backend #2697

wants to merge 41 commits into from

Conversation

richardhj
Copy link
Member

@richardhj richardhj commented Jan 26, 2021

Q A
Fixed issues N/A
Docs PR or issue TODO

I made some thoughts on how we can enhance the Contao backend and evolve a powerful ecosystem. First of all, I want to present my list of requirements that helps understanding why I decided on certain things.

Requirements and decision on the concept

  1. The Contao backend shouldn't be an immutable part of the Contao core-bundle; rather, it should be extendable, and it should be seen as a part of the App (as opposed to bundle).
  2. Developers should easily add new nodes to any part of the layout, e.g., new secondary navigation in the sidebar, new element to the header bar, etc., pp.
  3. Developers should be able to modify the appearance of the backend easily.
  4. Contao generates server-generated HTML and should continue so. We don’t want to maintain a JS-SPA, as it adds higher complexity to the project (and: Contao is a PHP framework!). Extendability with SPAs is a difficult task.

Methods

  1. Introduce a new "backend theme ecosystem" that is powered by Symfony Encore. Symfony Encore will do all the asset handling.
  2. Use a utility-first CSS framework for better extendability and long-term maintainability.
  3. Making use of Twig templates for improved template inheritance.

This PR is a progressive enhancement. At the moment, the “old backend modules” are not touched and are just being outputted in the page layout. We will slowly introduce a new backend ecosystem. Next is a rework of the DC and the request framework.

Design

Screen Shot 2021-01-26 at 23 43 01

Screen Shot 2021-01-26 at 23 43 53

Screen Shot 2021-01-26 at 23 44 38

(Subject to change. The search won't be part of this PR.)

Design decisions

The white background on the <main> controller was removed from the be_main template and moved to an atomic template. This allows designing backend modules with a custom design.

I will create multiple templates that support different design cases:

  • Container with white background and shadow (looks sleek on the gray background)
  • Multi-Column-Layout
  • Full-Width Container without width constraints.

I will provide a style guide if the time comes.

I am very enthusiastic about this. The new backend will allow us to build customized backends.

And, there is a dark mode as well 🌚 It can be toggled with adding the CSS class dark to the page. We then can trigger the dark mode with a toggle, per user config and per browser settings (with some JS).

Why I chose a utility-first CSS framework

TailwindCSS offers a range of crucial benefits, but most importantly Maintainability and Extendability.

  1. Maintainability. I don’t need to explain that the current CSS system in Contao is hard to maintain. A huge main.css and a couple of other CSS files that are hard to make sense of. But also modern approaches with SASS and “imports” lack maintainability issues as projects grow.
  2. Extendability. This is addressed in various ways. First, you can easily override a template and modify any part of the template. Secondly, third party bundles can quickly impact the design. Third, you can build the theme locally with a custom config using Encore effortlessly. No conflicting CSS and no need for “!important” whatever other bundles will want to modify!

I know that some are no big fan of CSS frameworks like Tailwind. However, we need to talk about alternatives then. We need to discuss how other design system choices can handle our criteria, i.e., the maintainability and extendability concerns as good as TailwindCSS does.

Some blog posts help to understand utility-first CSS frameworks:

  1. https://adamwathan.me/css-utility-classes-and-separation-of-concerns/
  2. https://www.algolia.com/blog/engineering/redesigning-our-docs-part-4-building-a-scalable-css-architecture/
  3. https://frontstuff.io/in-defense-of-utility-first-css

As most custom themes want to modify the template nonetheless (e.g., to add a logo or whatsoever), coupling the design system with the HTML just makes sense here.

Features

Create a reusable backend-theme

Backend theme developers have to make use of Encore. Internally, we are using Encore Twig functions to insert the correct file assets of the current theme on the page:

{{ contao_backend_link_tags('app') }}
{{ contao_backend_script_tags('app') }}

Theme designers, therefore, define their webpack config and put the dist files in the public folder of the bundle.

// assets/webpack.config.js

const Encore = require('@symfony/webpack-encore');

Encore
    .setOutputPath('../src/Resources/public/')
    .setPublicPath('/bundles/acmecontaocustomtheme')
    .setManifestKeyPrefix('bundles/acmecontaocustomtheme')

    .cleanupOutputBeforeBuild()
    .enableSourceMaps(false)
    .enableVersioning(false)
    .disableSingleRuntimeChunk()
    .enablePostCssLoader()

    .addEntry('app', './js/app.js')
    .copyFiles({
        from: './images/',
        to: 'images/[path][name].[ext]',
    })
;

module.exports = Encore.getWebpackConfig();

Theme designers then add their backend theme to the registry and they are ready to go. The theme is selectable in the backend.

services:
  Acme\ContaoCustomThemeBundle\ContaoBackendTheme\BackendTheme:
    tags:
      - { name: 'contao.backend_theme', alias: 'acme_custom' }

They also need to tell Contao where to find the entrypoints.json to include the assets from.

// Acme\ContaoCustomThemeBundle\ContaoBackendTheme\BackendTheme

final class BackendTheme implements BackendThemeInterface
{

    public function getThemePath(): string
    {
        return 'web/bundles/acmecontaocustomtheme/entrypoints.json';
    }
}

Change color palette with CSS variables

You don't need to build a custom theme for changing the colors or standard variables. You can add a custom CSS file and easily override the color palette by making use of CSS variables.

if (TL_MODE === 'BE') {
    $GLOBALS['TL_CSS'][] = '/bundles/acmecontaocustomcss/be_custom.css';
}
/* be_custom.css */

:root {
    --color-primary-50: #FFFFFF;
    --color-primary-100: #FEF6FA;
    --color-primary-200: #FAD2E5;
    --color-primary-300: #F5ADD0;
    --color-primary-400: #F189BB;
    --color-primary-500: #ED64A6;
    --color-primary-600: #E8368C;
    --color-primary-700: #D31872;
    --color-primary-800: #A51359;
    --color-primary-900: #770E41;
}

Build the backend locally

For backend themes built locally, you need to use Encore as well. You need to set the local theme path in the config:

# config/config.yml

contao:
  backend:
    theme_path: '%kernel.project_dir%/web/layout/backend/entrypoints.json'

Also, you need to set-up Encore correctly. You can see that the "output path" matches the path above.

// webpack.config.js

const Encore = require('@symfony/webpack-encore');

Encore
    .setOutputPath('web/layout/backend')
    .setPublicPath('/layout/backend')
    .setManifestKeyPrefix('')
    
    .enablePostCssLoader((options) => {})
;

backendConfig = Encore.getWebpackConfig();
backendConfig.name = 'contao_backend';

module.exports = [backendConfig];

I created a tailwind preset that allows loading the Contao config (colors etc.).

// tailwind.config.js

module.exports = {
    presets: [
        require('@contao/backend/tailwind-preset')
    ],
    theme: {
        extend: {
            colors: {
                brand: '#ff0000'
            },
        },
    },
};

More details are available under https://github.com/richardhj/contao-backend-test-installation/blob/main/README.md.

Set a theme globally for all users

One can set an already installed backend theme for all users globally. This disables the select in the user profile.

# config/config.yml

contao:
  backend:
    theme: 'my_theme'

Test installation

I set-up a test installation to test all new features: https://github.com/richardhj/contao-backend-test-installation.

When working on this PR we should split the discussions into two parts: a technical part a design part.

Dependencies / Future

This PR softly depends on #2638 (official Twig support). Multi-inheritance is crucial in the concern of extendability.

In the near future, we want to address more issues:

  1. Rework the Ajax handling in the Backend, integrate Hotlink Turbo (which is officially supported by Symfony UX soon).
  2. Create a new dashboard that can be extended.
  3. Make use of sub-requests and fragments.

In the long-term future, there are other things to do:

  1. Rework DC_Table, decoupling templates, and controller.
  2. Switch to Symfony Forms for the backend. Make use of „Symfony UX“ packages for the widgets.

Acknowledgments

I like to thank @m-vo and @may17 for their feedback and enthusiasm.

Notes on BC:

  • When a non-standard backend theme (other than "flexible") is used, the old theme should be used. (BC removed for Contao 5)
  • When a customized be_main.html is detected, the old theme should be used. (BC removed for Contao 5)

All compatibility changes will be noted here.

  • The twig menu headerMenu was changed significantly. Some menu items were removed from this menu. Those items were added to the new userMenu. The old headerMenu Knp menu contained HTML as labels (<button type="button" id="burger">) which is fixed now.
  • When custom CSS is added to the backend, it'll still work, except for CSS that addresses the layout sections (header, sidebar, etc), as the DOM was changed for those sections.
  • The parseTemplate hook won't work for the be_main.html5 template anymore, since it's not used anymore (besides the BC layer is active).

No other compatibility issues expected.

Deprecations

  • Using $GLOBALS['TL_CSS'] and $GLOBALS['TL_JAVASCRIPT'] keeps being supported for now, however adding them to BackendTemplate will be deprecated (the whole be_main.html is deprecated).
  • Template::getLocaleString() and getDateString() will be marked as internal. Needs to be addressed in further PRs.
  • BackendThemes::getThemeNames() is deprecated. This method only returns "old" backend themes. The new BackendThemes service with its method getThemeNames() will return only "new" backend themes registered in the container.
  • The fullscreen option is removed from the user settings.

TODO

  • Automatically detect current backend theme in contao_backend_link_tags() twig function
  • $GLOBALS['TL_CSS'] and JAVASCRIPT should be rendered within contao_backend_link_tags() twig function
  • Extract CSS from system/themes/flexible/main.css into a new file and revert changes on these CSS files
  • More atomic twig templates (with {% blocks %}) for easier extendability
  • Each theme should be able to provide twig templates, that will be loaded in the correct order
  • When a global theme is set (contao.backend.theme), the select field in the profile settings is disabled. Do we want to let users override the backend theme even if a global theme is set?
  • Design stuff :-)

@aschempp
Copy link
Member

When working on this PR we should split the discussions into two parts: a technical part a design part.

I would suggest to create two separate issues for that, wdyt?

@m-vo
Copy link
Member

m-vo commented Jan 27, 2021

While I agree that we shouldn't mix these topics when discussing, IMHO the technical part is the needed groundwork for (any) design rework.So maybe we should focus on this first before we start a second discussion.

@richardhj
Copy link
Member Author

richardhj commented Jan 27, 2021

To give the discussion a direction, there are four things to discuss (in that order):

  1. The concept: Do we agree with the idea to not create a SPA? Are we going to refactor the DC_Table?
  2. The Encore implementation: Twig function, EntrypointLookupCollection, the "BackendThemes" registry, and BackendThemeInterface
  3. The CSS Design system: Template-Driven Development / Utility first (i.e., TailwindCSS, and AplineJS as it is the same discussion)
  4. The appearance: Sticky footer, Colors, Shades, Width constraints, etc. pp.

Let us find a consensus on the first point and proceed then.

@may17
Copy link

may17 commented Jan 27, 2021

I think we should put the discussion on a higher non tech level. Imho one of the biggest problems of the core development is the technical focus but the contaos admin control panel isn't for developers only.

So one of the first questions should be "Who are our consumers and what are their needs"?

@Total-Reality
Copy link

Thank you very much for your ideas. It looks and sounds great.

The biggest disadvantages of the current backend are the missing ajax features. This and some other reasons result in a too slow and too laborious work in many situations. Other CMS are much further in this regard.

A backend search is a very good feature... Chapeau!

A toolbar with the last used backend dialogs whould be interesting too. I often jump between five or six dialogs in several situations.

@richardhj richardhj mentioned this pull request Jan 28, 2021
4 tasks
@aschempp aschempp added the up for discussion Issues and PRs which will be discussed in our monthly calls. label Feb 1, 2021
@leofeyer
Copy link
Member

How does your theme look on wide screens? This is how the current one behaves:

@richardhj
Copy link
Member Author

In order to simplify this PR and make changes as smooth as possible, I made the following assumptions and changes:

Assumptions:

  1. This PR can be seen as a new dress for the old backend. We do not touch the DataContainer.
  2. I did not touch Javascript components and this PR does not introduce compatibility issues JS-side.
  3. I removed the option to select a custom backend theme (c15069e). You can, however, still replace Twig templates and override CSS variables to customize almost any part of the backend.

Screenshot 2021-11-25 at 14 09 30 copy

Further PRs therefore should:

  1. Introduce a way to completely override the backend theme, i.e., the entrypoints.json file. Alternatively, we might find a way to easily distribute theme presets, e.g., colors.
  2. Abandon Mootools.
  3. Refactor BackendMain controllers.

Dependencies:

@richardhj richardhj closed this Mar 10, 2022
@leofeyer leofeyer reopened this Mar 10, 2022
@leofeyer leofeyer added feature and removed up for discussion Issues and PRs which will be discussed in our monthly calls. labels Jan 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants