RFC: The architecture and philosophy of site templates

Created on 8 July 2025, 4 days ago

This issue outlines the proposed technical architecture for site templates, including how they should work, how they should be built, and what their overall design and implementation philosophies should be.

Site templates should be "Big Recipes". That means they are recipes, first and foremost, but they are approached differently than most recipes are. A prototypical example is the drupal_cms_starter recipe. Site templates differ from most recipes in at least the following ways:

  • They don't need to be composable.
    • Site templates are meant to be applied once, at the start of the project, not to extend existing sites.
    • Site templates do not need to be idempotent.
    • Compatibility with other site templates is not necessary. If two site templates aren't compatible but want to intermix, they should be refactored into smaller recipes.
    • Similarly, a site template should not be built on top of another site template.
  • They care about looks.
    • Site templates should integrate heavily with Experience Builder (XB), which allows a look and feel to be packaged in configuration.
    • Site templates should depend on a theme (or multiple themes) as design systems – libraries of components, and their associated styles, for building out the look in XB.
    • They can ship custom components (probably JS components, which are XB configuration entities) to augment the design system's components.
    • They should ship content templates (an XB configuration entity) that use the design system's components to define standard looks for the site template's content models.
  • They ship content models and sample content: Most recipes don't ship a lot of content, partially because most recipes don't necessarily know what the desired content model will be. Site templates, on the other hand, are opinionated about the content model – they know what content types they have and how they are configured. They can include as much default content as they want.
  • They should be built atop common parts: Templates can use any combination of smaller recipes (core, contrib, or custom).
  • They should be comprehensive and strongly opinionated: The job of a site template is to provide a near-feature-complete site out of the box.
  • They cannot, on their own, affect the installer.
    • Most site templates should be apply-able by the Drupal CMS installer (i.e., Recipe Installer Kit β†’ ) – they should work in drupal/cms.
    • We don't want to require site templates to provide an accompanying project template; Drupal CMS's existing infrastructure should be able to accommodate custom or contributed site templates.
    • If a site template wants to affect the installer, it must release a separate project template to accompany it, which can have a custom install profile (ideally based on Recipe Installer Kit).
  • They should include some specialized metadata for Recipe Installer Kit.
    • A site template's recipe.yml should have information that you might not find in its composer.json, such as an extended HTML-supporting description, and screenshots with alt text.
    • Recipe Installer Kit will be responsible for exposing these templates in the installer for a user to choose from; it will discover the available templates by scanning for recipes that have type: Site in their recipe.yml file, and pulling the additional metadata from its extra section.
  • They need to include a composer.json.
    • Site templates are still recipes, so their project type should be drupal-recipe.
    • Like any other recipe, they should be published on drupal.org as general projects. (Obviously the existence of a marketplace may change this, but at this time we do not have any clarity on how.)
  • They do not provide update paths: They are recipes, and opinionated configuration updates are a problem for core to solve.
🌱 Plan
Status

Active

Component

General

Created by

πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @phenaproxima
  • πŸ‡ΊπŸ‡ΈUnited States Kristen Pol Santa Cruz, CA, USA

    Thanks. @phenaproxima. This is very helpful!

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    I think this is a great starting point!

    I strongly agree with They don't need to be composable.

    Curious why this is in Drupal CMS issue queue and not Drupal Core?

    Also agree with the statement: They care about looks.

    I strongly disagree most of the sub bullets under: They care about looks.
    I do agree integrating with XB should be possible, but it should not be the goal.

    Agree with:

    • They ship content models and sample content
    • They should be built atop common parts
    • They should be comprehensive and strongly opinionated

    They cannot, on their own, affect the installer
    I assume this is technical. I have no issue with this restriction.
    Why does the CMS installer have to be involved, is it purely the recipe magic that's needed?

    They should include some specialized metadata for Recipe Installer Kit. Maybe reword this a tad to be more generic to include the custom installers mentioned elsewhere.

    Strongly agree with:
    They need to include a composer.json.
    They do not provide update paths

  • πŸ‡ΊπŸ‡ΈUnited States rszrama

    Can we get the various verbs in the RFC formatted according to https://datatracker.ietf.org/doc/html/rfc2119? Almost every point in here uses "should" in a way that means "we expect it to, but it doesn't necessarily have to" according to RFC 2119. This makes requirement levels of certain bullet points ambiguous. (For example, saying a template needs to do something but only should conform to the point is contradictory.)

  • πŸ‡¬πŸ‡§United Kingdom catch

    They don't need to be composable.
    Site templates are meant to be applied once, at the start of the project, not to extend existing sites.

    I can agree with this in principle but it gets very tricky in practice.

    If site templates can only be applied by the installer, and not once a site is installed, then that means they cannot be installed via project browser - at least until project browser can be embedded in the installer which could be a long way off still.

    However it could be possible to allow them to be applied to a site that has just been installed, but is mostly empty.

    e.g. install Drupal CMS, choose a project template inside project browser, apply the project template.

    Then it brings up what should prevent a site template being installed, is it:

    - the site is installed at all
    - another project template has been installed (some kind of key/value recipe log)
    - no restriction unless the recipe is incompatible with the existing config on the site (but strongly recommended to do only before or shortly after install)

    If the answer to this is we don't know yet, then that is fine, but for me it would be good to reflect the possible options and uncertainty in the RFC.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Just to clarify, my objection to the XB bullets is not that I don't think site templates should support XB.

    I think site templates should support XB
    It's more that site templates should work if XB is not used, or the builder chooses to use UI suite instead.

    ✨ Adopt UI Patterns 2 to prepare developers and users for Experience Builder Active

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    @rszrama: Huh, good point about the RFC-words. Adjusted it to clarify.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    @nicxvan, I think the use of the RFC 2119 phrasing should ease your concerns. Site templates are responsible for delivering a complete look and feel, but how they go about doing that is, ultimately, their own business.

  • πŸ‡¦πŸ‡ΊAustralia pameeela

    However it could be possible to allow them to be applied to a site that has just been installed, but is mostly empty.

    This is the idea, and that's why it's worded as "at the start" rather than "during install." There are a number of reasons that we can't apply it before the Drupal install occurs. Most obviously, without Drupal being installed we can't use any Drupal tools, so it is limiting and increases the complexity. Separately, the cPanel auto-install tools run the actual installer (for obvious reasons we can't/won't try to change this) so anything that we do in the install is not available to those users.

    So basically it would just be that "site templates" as a category wouldn't appear in the full Project Browser. The selection of a site template would be limited to this post-install onboarding process, and once you have either selected a template or opted out (by saying you wanted to start from blank) then you wouldn't be able to do it again.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Responding to #5: "at the start of the project" is certainly ambiguous wording. I don't know if, from a specification standpoint, we actually care about when a site template could be applied. It could be at install time, it could be just after install time (initial onboarding), or at some other point.

    The idea we're trying to communicate is that a site template should think of itself as having a blank canvas to work with.

    EDIT: Posted this at the same time that @pameeela posted the previous comment. D'oh!

  • πŸ‡¦πŸ‡ΊAustralia pameeela

    Yeah actually further to what @phenaproxima says in #10, I don't think there are any plans to proactively disallow a site template from being applied to an existing site -- it's just a recipe, so someone who knows how to download and apply a recipe could do it whenever. But it's unlikely to work very well, so the aim would just be to prevent it from being easily do-able in the UI.

    At least, that's how I'm thinking of it.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    That new language clears most of my concerns.

    I'd say we probably want to think about someway to strongly, strongly discourage applying site templates after a certain point.

    I think one of the main targets of site templates and CMS users will need something to help keep them from shooting themselves in the foot trying to apply a second site template once it's too late.

    I agree in general though that defining that point and mechanism doesn't need to be done yet.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Thanks #9 and #10 help a lot and sounds reasonable.

    I still think the text could use clarification because "They are meant to be applied once, at the start of the project, not to extend existing sites." is for me a bit beyond ambiguous into potentially misdirecting people.

    A site by definition 'exists' once it's installed (especially if that happens on cpanel and it's live on the internet). This is especially a big difference from distributions and install profiles which by definition can only be chosen during the installer. Maybe something like 'meant to be applied once, very early in the lifecycle of a site, not to extend established sites' would work?

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    I like it!

  • πŸ‡¨πŸ‡¦Canada deviantintegral

    This issue is my favourite thing since site templates were proposed!

    Site templates MUST NOT provide update paths. They are recipes, and opinionated configuration updates are a problem for core to solve.

    Is this really limited to core? Since recipes can depend on modules, I'd be surprised if site templates authors don't end up shipping small modules with tweaks or improvements that simply can't be done with config. For example, perhaps they depend on some module during the Drupal 11 cycle, and it's abandoned or replaced and they want to ship a template-specific update hook for Drupal 12. If you aren't defensive and ship even a stub module as a dependency, you could have unhappy users in the future (or a lot of manual support work).

    How about something like:

    Site templates MUST NOT provide update paths. They are recipes, and opinionated configuration updates are best handled by Drupal core or contributed modules.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    It's more that site templates like recipes are apply once and done.

    Modules that are part of it can update they can provide config updates if they need to. But once applied the site template never interacts with your site again.

    If the maintainer of the site template wants to add new features or remove them from their template they can at will since no sites that applied the site templates in the past can be affected.

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Compare this with distributions that have to care about sites using it for every version of the distribution ever.
    You have to test updating too the current certain for every version released to be safe.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    @deviantintegral: We could probably rephrase it, sure -- you are correct that update paths are the responsibility of persistent runtime code, which means core and contrib modules.

    Being recipes, site templates can't provide update paths even if they wanted to, because recipes can't have code and that's that. So it's a hard technical limitation, but it's also a philosophical one; site template authors shouldn't be thinking about update paths, because a site template is purely a starting point.

    Here's where the philosophical part enters into it: imagine if someone ships a custom project template which includes a custom profile that applies a site template, with the intention that the profile will remain active in the background and run update hooks. That would be technically feasible, but it would violate the intention and purpose of a site template and run into many of the same problems that traditional distributions faced.

    That's why update paths are prohibited with that "MUST NOT" directive.

  • πŸ‡¬πŸ‡§United Kingdom catch

    For example, perhaps they depend on some module during the Drupal 11 cycle, and it's abandoned or replaced and they want to ship a template-specific update hook for Drupal 12. If you aren't defensive and ship even a stub module as a dependency, you could have unhappy users in the future (or a lot of manual support work).

    Recipe unpacking means that even if this module was a dependency of the site template (or a recipe it uses) when the recipe is applied, as soon as it's been applied it becomes a direct dependency of the site in the project composer.json.

    There's therefore no way for the recipe or site template to 'take over' that module as a part of itself. The site would still have that composer dependency even if the physical code for an updated module was shipped elsewhere somehow.

    If the person or organisation that produces the site template wants to help users who are now stuck on an abandoned module and unable to update, they'd have to become co-maintainers or gain ownership of the project and provide some kind of upgrade path or graceful obsolecense path there. The advantage here is then any user of that module would benefit.

    It would be possible to put the code in a new project in a different namespace, then tell users to install that new project via project browser and uninstall the old project. Project browser doesn't get have a way to remove composer dependencies yet so you're down to cli composer remove until 🌱 [meta] composer require / install module discrepancy issues Active is resolved to actually remove that dependency from the site.

    More discussion of the general problem here 🌱 Try to reduce unused composer dependencies Active .

  • πŸ‡ΊπŸ‡ΈUnited States rszrama

    Thanks for the update! A couple follow-ups...

    In the marketplace proposal β†’ shared out a couple weeks back, patching was indicated as not allowed, but this specification makes no mention of patching one way or the other. I suppose the difference is whether or not a template would be eligible for inclusion in a Marketplace, not whether or not a template can use patches.

    1. Can we get a clarification, perhaps in "Site templates are built atop common parts." that "Site templates using their own project templates MAY include patches to included projects." If it needs to be more specific, happy to wordsmith the language. I also don't think it would be bad to indicate the patches must be hosted on d.o, e.g., "... MAY include patches to included projects that are attached to issues in those projects' issue queues." (This can avoid a future supply chain attack where someone swaps out the patch after installation to something nefarious.)

    The meaning and intent of "Site templates MUST NOT, on their own, affect the installer." is still a bit ambiguous to me. I can imagine various reasons why a template may not use Drupal CMS as its base, for example. But even with what we've done in Kickstart, I do think we're compliant. We have:

    • Commerce Kickstart project template
    • Commerce Kickstart install profile based on Recipe Installer Kit
    • Commerce Kickstart Base recipe (which I believe you would regard as the site template in this formulation)
    • Commerce Kickstart Demo recipe (which optionally builds out the product types, catalog, and imports product content)

    Related to my point of clarification re: patching, part of the need here is for us to be able to patch a Bootstrap Basic Image Gallery for things to work well in our use of Bootstrap / Layout Builder. Maybe that goes away once we can switch to XB and we don't need to patch and don't care to maintain our own project template, but this is the current state of affairs.

    Finally, if we're going to require "Site" as the type, then in our case I suppose it would just be Commerce Kickstart Base? What about Commerce Kickstart Demo, which depends on the Base recipe. I suppose that could also be considered a "Site" recipe? The problem is that then violates the principle of "Similarly, a site template SHOULD NOT be built on top of another site template."

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    patching was indicated as not allowed

    That's a great point and should be clarified.

    I think site templates MUST NOT patch -- at least, not in tagged releases. Patching breaks automatic updates (Package Manager will refuse to work if it detects the patcher plugin) and can cause great pain for non-technical end users if a patch ceases to apply, or conflicts.

    But I could be wrong here; we should think this bit of it through before we make it part of the spec. I know @catch has some strong opinions about patching.

    My own feeling is this: generally, patching is fine for an established site to do, because it knows its own idiosyncracies. But a site template has no business doing it because of the updating-related and release management problems it can introduce, especially when you consider the target audience for site templates.

    The meaning and intent of "Site templates MUST NOT, on their own, affect the installer." is still a bit ambiguous to me

    "On their own" is the key phrase here. A site template needs to be a recipe, and not "a recipe plus an install profile", or anything like that. Just a recipe, full stop. Install-time stuff is the province of install profiles, and site templates need to stay in their lane. They absolutely should not be coupled to -- or dependent upon -- a particular install profile. Added a point to clarify that a bit.

    Bear in mind the distinction between a site template, which is just a recipe with strong boundaries, and a project template, which is the full scaffolding for the entire code base. A project template has much more leeway in what it's allowed to do. drupal/cms is an example of a project template, as is core's drupal/recommended-project.

    Project templates can include site templates, but I don't think it should work the other way around -- site templates should never be coupled to specific project templates. (This is also part of why patching in a site template should be verboten.)

    So for your use case, it sounds like you are providing a project template, which is not part of this spec; the Commerce Kickstart base recipe, as you say, is probably the site template.

  • πŸ‡¬πŸ‡§United Kingdom catch

    . I know @catch has some strong opinions about patching.

    My own feeling is this: generally, patching is fine for an established site to do, because it knows its own idiosyncracies. But a site template has no business doing it because of the updating-related and release management problems it can introduce, especially when you consider the target audience for site templates.

    I was about to write something up and nearly cross-posted. This paragraph matches my own view too.

    A site template or recipe is supposed to be applied once, which means the site owner becomes reponsible for updating modules from then on.

    If a recipe is built for site owners who will be using package_manager/automatic updates/project browser (not even all of the site owners, just any of them), then those users cannot be expected to figure out why a patch doesn't apply, correctly find the new version of that patch if there is one, determine whether it doesn't apply because it was fixed, or re-roll the patch if it's still needed and there's no newer version, and then hand-edit composer.json depending on all of the above.

    Wasn't sure about this and had to double check with @phenaproxima, but the compose recipe unpacker ignores patches as well - so when you apply a recipe, the patch will neither be in the recipe's composer.json (because it's removed), nor the site's composer.json (because it wasn't pulled in), it will get un-applied.

    I think I've seen a few modules include patches in composer.json around, although I can't remember any off the top of my head. Those modules can update their patch list when the module itself is updated, but it means they'll need to chase new versions of whichever dependency they're patching. Also even though this is more robust than shipping with a recipe, it still doesn't handle if two different modules ship different patches.

    There are usually options other than patching, like including a shim module that overrides whatever it is that otherwise needs to be patched, or working with the maintainer to get things included, or forking - all of these have their own drawbacks too but they put the maintenance responsibility onto the developer, not potentially thousands of individual site owners who never knew they were applying patches in the first place.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    I think that explanation is pretty clear, and I'm going to put the prohibition in the spec. (We can always workshop it if there's strong disagreement.)

Production build 0.71.5 2024