This is a BC breaking change!
Manipulating Pico's $plugins array is a really bad idea. We've introduced the Pico::loadPlugin() method to safely load plugins at any time, however, Pico might do unexpected things when loading plugins too late. See the class docs of Pico::loadPlugin() for more details. Nevertheless, this change breaks BC to Pico 1.0. However, I don't know a single plugin that relies on manipulating the $plugins array. If you just want to load a plugin manually, use Pico::loadPlugin() instead.
Add new onPagesDiscovered event passing the unsorted pages array, move the $currentPage, $previousPage and $nextPage arguments from the onPagesLoaded event to the new onCurrentPageDiscovered event, remove the $twig argument from the onPageRendering event and rather trigger the new onTwigRegistered event for this. Also add the new onYamlParserRegistered and onParsedownRegistered events passing the YAML parser resp. the Parsedown instance. Allow plugin's to skip a page by setting the $id argument of the onSinglePageLoading event to NULL.
The vendor directory is the installation path of the `picocms/Pico` package. If `picocms/Pico` is the composer root package (as in pre-bundled releases), it should be identical to `Pico::getRootDir()`. However, if `picocms/Pico` was installed as composer dependency (e.g. by `picocms/pico-composer`), the vendor directory usually corresponds to something like `Pico::getRootDir() . "vendor/picocms/pico"`. The vendor directory is currently only used as a last resort to load Pico's sample contents.
Instead of using `*.config.php` files, use `*.yml` files to configure Pico. YAML is much easier to understand, more user friendly and (at least a bit) more error-tolerant, but still very powerful. Don't break BC by letting `PicoDeprecated` still read `config/config.php`.
Currently Pico::getTwigVariables() always returns the default twig variables and ignores all additions/changes made through the onPageRendering event. The method now returns the "real" variables array used by Twig.
Specifying a custom sort method usually means that all pages are sort by a plugin, so Pico's default alphabetical order is overwritten anyway. Letting Pico sort the pages first and discarding the result is burned CPU time...
As previously announced (see [Upgrade to Pico 1.0 page](http://picocms.org/in-depth/upgrade/)) we'll remove the default plugins `PicoParsePagesContent` and `PicoExcerpt` with the next Pico milestone. Needless to say, that you can still install both plugins without any problem - we'll add them to Pico's official [Plugins collection](http://picocms.org/plugins/) by then. Please note that the disadvantages of these plugins are still critical and we strongly advise to not use them. Please refer to the [Upgrade to Pico 1.0 page](http://picocms.org/in-depth/upgrade/) for details.
Execution order matters: if plugin A depends on plugin B, it usually means that plugin B does stuff which plugin A requires. However, Pico loads plugins in alphabetical order, so events might get fired on plugin A before plugin B.
Hence plugins need to be sorted. Pico sorts plugins using a dependency topology, this means that it moves all plugins, on which a plugin depends, in front of that plugin. The order isn't touched apart from that, so they are still sorted alphabetically, as long as this doesn't interfere with the dependency topology. Circular dependencies are being ignored; their behavior is undefiend. Missing dependencies are being ignored until you try to enable the dependant plugin.
This method bases on [Marc J. Schmidt's Topological Sort library](https://github.com/marcj/topsort.php) in version 1.1.0, licensed under the MIT license. It uses the `ArraySort` implementation ([class `\MJS\TopSort\Implementations\ArraySort`](https://github.com/marcj/topsort.php/blob/1.1.0/src/Implementations/ArraySort.php)).