Proposal: New theme file structure to Drupal

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
You are viewing a wiki page. You are welcome to join the group and then edit it. Be bold!

Note: This proposal envolved for discussion over http://groups.drupal.org/node/19817. Go there to get the background and continue the discussion.

This proposal is designed with following goals in mind:

  • Minimal amount of code changed, most of implementation is just reorganization of existing files
  • Better visibility for Drupal core templates and CSS
  • Clearer separation of functional and aesthetic parts of the theme layer
  • Offering several flexible and clear starting points for themers to build their work on

Implementation:

1. Create default core theme

We take advantage of already existing subtheme flow logic http://drupal.org/node/225125 but we introduce a fixed, core-provided first ancestor to a cascading theme chain. This "core theme" is the default fallback for Drupal rendering needs.

It's located in /themes/system directory (there are other naming options like /themes/core or /themes/default or /themes/base etc.

This core theme contains all the core css, js and tpl.php files moved over from /modules/* and /misc folders.

This brings visibilty to core-provided markup and styling and explains theme chaining system with a concrete example.

(Think it is as "Stark with actual files in it")

2. Create builder theme

We introduce an "builder theme", more stylized and fine-tuned theme than raw core theme, something that themer can customize in minutes and get instant professional look. It provides all utilities of a modern theme framework: grid engine, good typography etc. We could use 960gs, Blueprint, Framework X or build our own.

/themes/builder/builder.info is standard D6 theme .info file except following line:

base theme = system

That is the the main change: in order to function as they do now all existing themes should have that property set in their .info file. It is meant as clear answer to the existing painful question: "I start a theme from scratch but where from all this core styling is coming from?". Answer is "they are coming from the system theme". "How can I see this magical system theme?". The answer now is: "Go see themes/system, doh!"

(Think it is a "Zen Lite")

3. Provide clear starting points for themers to work

Explain themers that they have three starting points to base their theme on, based their workflow, convinience and expertise:

A: Base your theme on builder theme: set base theme = builder in your theme's info file. Get all the flexibility of the builder framework.

B: Base your theme on core theme: set base theme = system in your theme's info file. A simple solution, suitable for CSS-only themes.

C: Base your theme on clean state: do not set base theme in your theme's info file: no core CSS is loaded. This means a complex process of building "your own core theme" but offers the most freedom. If themer wants to, he can cherry-pick the essetial parts of the system theme by copying those to their theme directory.

All these entrypoints should be documented either in composite document themes/README.txt in respective subfolders eg /themes/system/README.txt

4. Split core CSS to functional and aesthetic markup.

Current core-provided CSS is very confusing: evolved over years it has become a mishmash of markup with no clear structure. It's also scattered between core's module markup, /modules/system/system.css, /modules/system/system-menus.css, /modules/system/defaults.css, /misc/print.css etc etc.

The proposed solution is to break this CSS apart based of nature of it's markup and provide modular components of CSS:

A: Functional CSS and JS:

  • Functional CSS pieces for UI controls -- usually JS-bound -- need to be present in any theme: core theme, builder theme, other drupal-bundled themes (garland), contrib themes. Not having them breaks the UI. Disabling or overloading that CSS should be very rare but some advanced themes may want to overload functional CSS and JS for these components (yellow fade technique or closable checkboxes) etc.
  • Examples of functional CSS: autocomplete, fieldsets, textarea grippie, password validator, table sticky headers + tabledrag, vertical tabs, text format selector, progressbar etc.
  • Styling these elements also requires defining a common, agreed CSS base to build on top to. It can either be default browser styles; a separate reset.css or a hybrid where reset and rest of CSS are present in same CSS (file(s)).
  • Functional CSS and JS should be put in /themes/system directory, having their own CSS namespacing and file naming convention. Every functional UI widgets markup should to be put ito a separate file. All functional CSS and JS are placed to /themes/system/style/ by default:

/themes/system/styles/ui-autocomplete.css
/themes/system/js/ui-autocomplete.js

B: Semi-functional, semi-aesthetic CSS:

  • There are CSS pieces in core what fall into gray area between being bit functional and bit aestetic. Some of them improve accessibility / legibility of UI and typography, some of them contain just CSS utilities "every theme has anyway".
  • Examples: form styling, clearfix, ul/ol/dl styles, blockquote styles etc.
  • Styling these elements also requires defining a common, agreed CSS base to build on top to. It can either be default browser styles; a separate reset.css or a hybrid where reset and rest of CSS are present in same CSS (file(s)).
  • More "functionalish" CSS is placed to /themes/system/styles/ by default
    /themes/system/styles/ui-forms.css
  • More "aesthetish" CSS is placed to /themes/builder/styles/ by default
    /themes/system/styles/typography.css

C: Aesthetic CSS:

  • Pure eye-candy. Core theme do not have aesthetic CSS layer, builder theme can have one: either default one or even better: a subtheme based on builder theme.
  • Aesthetic CSS is placed to /themes/builder/styles/ by default
    /themes/builder/styles/colors.css

Appendix 1: Proposed file layout for system theme

# No "base theme" line!
/themes/system/system.info

# Contents: "Core theme: a generic theme what provides the default implementation
# for all CSS/XHTML Drupal generates. The rest of core themes are based on
# this theme. You can base your theme on this by having a line
# "base theme = core" in your theme .info file.
# To start with clean state with no core-provided markup, uncomment that
# line. + ...warning about functional ui CSS..."
/themes/system/README.txt

# Basic layout a la Stark.
/themes/system/styles/layout.css

# Styles
/themes/system/styles/ui-autocomplete.css
...

# Javascript
/themes/system/js/ui-autocomplete.js
...

# Templates
/themes/system/templates/aggregator-feed-source.tpl.php
...

Appendix 2: Proposed file layout for builder theme

# "base theme = system"
/themes/builder/builder.info

# Contents: "Builder theme: a modern building-block theme /.../
# You can base your theme on this by having a line
# "base theme = builder" in your theme .info file. /.../"
/themes/builder/README.txt

# Styles, usual CSS framework stuff
/themes/builder/styles/grid.css
/themes/builder/styles/typography.css

# Rest of styles
...

# Javascript
...

# Templates
...

Known problems:

  • CSS and tpl.php inheritance work a bit different. tpl.php absolutely needs default implementation when CSS does not always have to (pehaps just functional/js css). So so even when you base your theme on void, you still get your themes/core/templates/ tpl.php files loaded. Does this breaks fallback / inheritance mental model?
  • There are still 140 theme functions what are hidden inside module files. Because of this the proposal above do not provide 100% visibility for theme files. See http://drupal.org/node/398294
  • Theme chooser page: we need to make sure user can not disable the core theme: we always need that fallback. We need either hardcode it to be always enabled and disable the "enable/disable" checkbox OR we could re-use module.info property "required = TRUE" and have that line in system.info file. Theme chooser page should be aware of that flag (just like module overview page).