picocms / Pico

Pico is a stupidly simple, blazing fast, flat file CMS.
http://picocms.org/
MIT License
3.82k stars 616 forks source link

Including PHP in theme #454

Closed nsrosenqvist closed 5 years ago

nsrosenqvist commented 5 years ago

I've been looking through the documentation looking for a way to extend twig from a theme. I want to include a simply cache busting filter but I'm not sure how I can add the code from a theme? I don't want to have to distribute a separate plugin for this one feature which is a hard dependency anyway and the theme can't be separated from it. Can custom code be loaded from within a theme or plugins distributed as a sub-folder of a theme? What is the recommended approach for this?

PhrozenByte commented 5 years ago

This isn't possible, Pico strictly separates plugins and themes. You'll have to create a separate plugin.

Anyway, you can (and should) add a dependency to the plugin in your theme's composer.json (and vice-versa in the suggest section of the plugin's composer.json if it's a hard dependency) to make sure it is installed when requiring your theme in your website's main composer project (assuming you're using a Composer-based installation of Pico, what is recommended in general and particularly for situations like yours).

nsrosenqvist commented 5 years ago

Are there any plans on enabling running code from within a theme? I know many other CMS's keep to the same policy but it makes it so much more inconvenient for many developers for when a theme is custom made and it's basically created as the entire site and not just a skin. Meaning, it's not meant to be reused or distributed but it's branded and with custom functionality for a single hosted site and the layout/styling is always kept in sync with the functionality (the code). For those use cases, when it's not for shared hosting and the site never intends to "change" theme, but simply keep developing its theme, can't it be allowed to run code from within the theme? Otherwise two separate code bases and repositories need to be maintained even though they are completely dependent on each other.

I was very frustrated with this hard separation of concerns when using OctoberCMS a couple of years ago, any small feature had to be released as a plugin and greatly increasing maintenance burden of projects, so I developed a Themes+ plugin that loaded code from within a theme into a "Theme" PSR-4 namespace. However, it got rejected from the plugin repository due to not being inline with their goals. Would a similar plugin be frowned upon or accepted into plugin lists or repositories (if possible to hook-in to Composer's autoloader when using Pico)?

Is there any reason why running code from themes couldn't simply be a config option in the installation where the host would decide if they want to allow it? That way it could be off by default but still be available for more customized installations.

PhrozenByte commented 5 years ago

Meaning, it's not meant to be reused or distributed but it's branded and with custom functionality for a single hosted site and the layout/styling is always kept in sync with the functionality (the code).

I totally understand your point! Actually this is pretty common, I'm facing the same problem with many websites. But it's rather easy to solve: You're not required to use Composer for your website-specific theme and plugin. Pico still (and always will) support local themes and plugins. Simply add both to your main Composer project resp. your website's Git repo (i.e. by adding the files to the plugins/MyPlugin/ and themes/MyTheme/ dirs), allowing you to manage content files, the website-specific theme and the theme-specific plugin all in one place. You can use picocms/pico-composer as a basis.

Are there any plans on enabling running code from within a theme? […] Is there any reason why running code from themes couldn't simply be a config option in the installation where the host would decide if they want to allow it? That way it could be off by default but still be available for more customized installations.

No, there are no plans to allow that in Pico's core. We truly believe that separation of concerns is a good thing. This is also the reason why we don't support Twig in content files. It's part of Pico's concept that neither content files, nor themes can introduce malicious code to the server (JavaScript is a different thing).

Anyway, this only concerns Pico's core. Thus:

Would a similar plugin be frowned upon or accepted into plugin lists or repositories

I don't see any reason why we should decline such a plugin, so, sure, we would accept such a plugin (as long as it meets the submission guidelines).

However, I'd rather recommend keeping it as simple as possible, i.e. not concerning Composer here. Simply write a plugin, check whether the file themes/<current theme>/<current theme>.php exists, include it (see Pico::loadLocalPlugins()) and use Pico::loadPlugin() to load the plugin. However, I'd still recommend using the main repo approach described above, it's easier :smile:

nsrosenqvist commented 5 years ago

@PhrozenByte thank you for your detailed response. Good to know the official stance on this! Then for now I'll probably just make one plugin containing the specialized functionality and will evaluate later if it's worth splitting up into different plugins.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in two days if no further activity occurs. Thank you for your contributions! :+1: