Open james2doyle opened 8 years ago
Then we use something like the service provider in Laravel to load plugins by their class name.
I'd prefer the approach Symfony uses with it's bundles. Rather than a list of class names, you instantiate a new instance of the class and pass that. This would allow the end user a little more control over how a plugin is instantiated if necessary, but remain simple to use if not.
$config['plugins'] = [
new Phile\Plugin\PhpFastCache,
new Phile\Plugin\SimpleFileDataPersistence,
// new Phile\Plugin\FilterByKey,
new WarpaintMedia\Phile\TwitterPlugin,
// ...
];
Any object or data references that need to be passed to the plugin can be done so via setter methods which would be defined on an interface that a plugin implements.
Instead of having a /protected folder, we should just have a /public folder. Everything else can be locked down.
This can be used to store uploads or arbitrary things that don't belong in /content or /themes.
I'm of the opinion that the /content
folder should essentially be a public folder. I personally find it much more convenient to store any assets related to a particular page within the same directory as the page's markdown file. Having to store such assets in a separate folder would be a hassle.
My preference would be to treat /content
as public, but have requests for markdown files intercepted by Phile for rendering.
Everything else sounds good to me. Having a skeleton app which has phile as a requirement for people to use with create-project is a good idea and would resolve #298. A simplified and modular configuration would certainly be helpful for plugins.
Rather than a list of class names, you instantiate a new instance of the class and pass that. This would allow the end user a little more control over how a plugin is instantiated
This sounds interesting. Seems a little more advanced than the class as a string. Is there a case where people would start passing things to constructors? If yes, the benefit of more control seems a little more noisy.
Is there any case where you would need access to a constructor in the config?
I'm of the opinion that the /content folder should essentially be a public folder.
Except a public folder would have things like the main index.php
file, the .htaccess
or webconfig
file, also the favicon and maybe a robots.txt
file. These would never be in the content folder since the server doesn't treat that as the root.
Is there a case where people would start passing things to constructors?
Most likely not. The only potential use case I could come up with would be to to re-use a plugin with an alternate configuration by passing in a key name or something. 99% of the time I'd expect the constructor would be unused though.
However it doesn't seem more noisy to me. From an end user perspective the only difference is using new \Example\Class
vs \Example\Class::class
or '\Example\Class'
From a developer perspective their plugin would just have to extend an AbstractPlugin
class to gain access to Phile resources. In my experience using new \Example\Class
works better with editor auto-complete and refactoring tools. \Example\Class::class
should work ok, but an actual string usually fails.
Except a public folder would have things like the main index.php file, the .htaccess or webconfig file, also the favicon and maybe a robots.txt file.
I don't really see any issue with mixing those in with the content markdown files. Phile should only be concerned with requests to .md files, anything else would be served as is. Someone potentially loading a .md file directly doesn't strike me as an issue. With proper configuration, it shouldn't happen anyway.
I think merging a content
folder with a public
folder would just be messy. I screwed up the lib
folder by adding cache
in there. In hindsight, it makes no sense, but I thought I was just putting similar things together.
Having server-related files in the markdown content folder just seems like a code-smell. Non .md
files will then need to be ignored when filtering through the folder contents. Seems like unnecessary pollution to add to the folder. I would expect that the additional files would impact performance for larger sites.
For the new
up of plugins in an array, I would want to avoid "functionality" in a config file. That being said, I can imagine a case where you would want to have 2 of the same plugin, but would want them differentiated in some way. Not sure how that would work without the new
up class and adding arguments to the constructor. So maybe that is a good solution!
Remove both config files. Add a /config folder and load all files inside it.
And in which priority they will be loaded? So there should be smth like
00-default.php
99-custom.php
or smth like that.
Add a /public folder Helper functions in templates +1
I put some work toward the ideas presented here, mainly splitting the project into a separate core and skeleton app. I'd like to ask for opinions before doing too much more work.
I've created two branches to work with, core-split and skeleton-split. One of these would ultimately be converted into it's own repository. I went the route of changing the core to phile-cms/phile-core and leaving the skeleton app as the current name.
I also added a composer script to handle the setup after a composer create-project call. It will ask for basic parameters and generate the config.php and also the cache directories.
Any input is welcome. If the direction looks good I can continue trying to make improvements. Otherwise it could be scrapped and a new approach tried.
While way to late for the party here are my thoughts working with the code at the moment:
Right now we have a custom vendor setup as /lib/vendor. I think this should be removed and just use the default /vendor.
Don't see an issue with that. But personally I don't mind lib/vendor, it makes manual updating the core easy: "just copy lib/".
Move the Phile core into a composer package, and use a composer create-project command to generate a skeleton app that has everything setup.
Don't see an issue with that.
This would remove the need to manually set the encryptionKey or do a setupCheck. This could even be interactive like composer init.
If there's a zip download which runs without composer - which I feel strongly about - there's a need for a PHP setup implementation.
Move all the plugins onto packagist. Plugins are installed into /vendor using composer install/require.
It's a PITA to develop in that setup (dev-setup, push to all those different repositories, keep versions strings in order, …). Theoretically yes, practically not a fan.
Would become something like:
This could be done nonetheless.
Remove default_config and config
The config situation could be improved, but I don't see a benefit of having half a dozen of config one-liner files. As @Frodox mentioned other questions arise: Is the file order important? Does plugin loading need to reflect the file order? Is there a naming convention so a config matches a plugin? This could be become complicated fast without providing real world benefits.
Plugins have routes
Plugins are already able to do that? I have to see a concrete implementation for an opinion.
Add a /public folder
Sounds like the right thing to do, but I'm rather sceptical again. This would mean you can't serve assets out of plugin-ins? Are additional conventions and/or moving files on plugin de-/installation required? Not a fan if true.
Helper functions in templates
This sounds somewhat complicated to do if the core should stay template-engine agnostic. Need to see an implementation.
Here's is my 2.0 wishlist:
defines()
as possible into a config parametercontent/
for the kown behaviour. (ServiceLocator?)Maybe:
Phile 2.0
Lately I have been using Laravel and Slim and have noticed some nice things we can steal. It has been a while since I used Phile, but I have been using it for the past couple of weeks and noticed some of the missing or awkward choices.
This is my pitch for 2.0. This is simply a proposal that is open for discussion, not a demand or order for a particular direction.
Use default composer dir
Right now we have a custom vendor setup as
/lib/vendor
. I think this should be removed and just use the default/vendor
.All things composer
Move the Phile core into a composer package, and use a composer create-project command to generate a skeleton app that has everything setup.
This would remove the need to manually set the encryptionKey or do a setupCheck. This could even be interactive like
composer init
.All plugins in composer
Move all the plugins onto packagist. Plugins are installed into
/vendor
usingcomposer install/require
.Then we use something like the service provider in Laravel to load plugins by their class name.
For example:
Would become something like:
To disable a plugin, simply remove it from the list or comment it out. I describe plugin config in the next section.
Remove default_config and config
Remove both config files. Add a
/config
folder and load all files inside it.Then we can have our plugin configs in that folder, but also split up by name.
Any default Phile config stuff would be in the Phile Core package.
Plugins have routes
Add the ability to set a route for the plugin to be reached at.
This means a plugin could be used almost like a controller. Useful for AJAX/Form submission stuff.
Pages as a collection
The pages array or class should instead be a Collection.
This allows easy filtering, sorting, reducing, and searching, but as part of the Pages object. This makes manipulating the pages array in a plugin (but also in Core) much easier.
Add a /public folder
Instead of having a
/protected
folder, we should just have a/public
folder. Everything else can be locked down.This can be used to store uploads or arbitrary things that don't belong in
/content
or/themes
.Helper functions in templates
These would be really simple to add in Twig.
{{ url('/some-page') }}
instead of{{ base_url }}/some-page
{{ theme('/css/style.css') }}
instead of{{ theme_url }}/css/style.css
{{ render('/hidden/file.md') }}
would render a file in the/content
directory.{{ route('pluginName.pluginRoute') }}
would be able to resolve a plugin route to a real Phile route{{ meta('a_meta_key', 'default value if missing') }}
would allow you to fetch meta, or have default metaIn the end, I think these changes would make Phile much nicer. It may be a little more advanced, but I think the benefits outweight the downsides.
Anyone have any comments on this?