diff --git a/.gitignore b/.gitignore index 825c513..8e11af4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ desktop.ini .DS_Store ._* +# Travis +/build/phpdoc-*/ +/build/phpdoc-*.git/ + # Composer /composer.lock /composer.phar @@ -19,11 +23,11 @@ desktop.ini /config/config.php # User themes -/themes +/themes/* !/themes/default # User plugins -/plugins +/plugins/* !/plugins/0?-* !/plugins/1?-* !/plugins/DummyPlugin.php diff --git a/.travis.yml b/.travis.yml index 331173c..aa0af02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,13 +8,29 @@ php: - hhvm - nightly +matrix: + allow_failures: + - php: nightly + fast-finish: true + +install: + - composer install + +before_script: + - export PATH="$TRAVIS_BUILD_DIR/build:$TRAVIS_BUILD_DIR/vendor/bin:$PATH" + script: - - find . -type f -name '*.php' -print0 | xargs -0 -I file php -l file > /dev/null + - phpcs --standard=phpcs.xml "$TRAVIS_BUILD_DIR" + +after_success: + - deploy-phpdoc-branch.sh before_deploy: - - composer install - - composer dump-autoload --optimize - - tar -czf "pico-release-$TRAVIS_TAG.tar.gz" .htaccess README.md CHANGELOG.md CONTRIBUTING.md composer.json composer.lock LICENSE config content-sample lib plugins themes vendor index.php + - deploy-phpdoc-release.sh + - composer install --no-dev --optimize-autoloader + - find vendor/ -type d -path 'vendor/*/*/.git' -print0 | xargs -0 rm -rf + - mv index.php.dist index.php + - tar -czf "pico-release-$TRAVIS_TAG.tar.gz" README.md LICENSE CONTRIBUTING.md CHANGELOG.md composer.json composer.lock config content-sample lib plugins themes vendor .htaccess index.php deploy: provider: releases @@ -22,9 +38,7 @@ deploy: file: pico-release-$TRAVIS_TAG.tar.gz skip_cleanup: true on: - repo: picocms/Pico tags: true php: 5.3 sudo: false - diff --git a/CHANGELOG.md b/CHANGELOG.md index 991b2ec..8a3fe95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,16 +9,24 @@ Released: - all contributors and users which made this possible! * [New] New `markdown` filter for Twig to parse markdown strings; Note: If you want to parse the contents of a page, use the `content` filter instead +* [New] New PHP version check in `index.php` * [Changed] Improve documentation * [Changed] Improve table styling in default theme +* [Changed] Update composer version constraints; almost all dependencies will + have pending updates, run `composer update` * [Changed] Throw a RuntimeException when the `content` dir isn't accessible * [Changed] Reuse `ParsedownExtra` object; new `onParsedownRegistration` event +* [Changed] `$config['rewrite_url']` is now always available +* [Changed] `DummyPlugin` class is now final +* [Changed] Various small improvements and changes... * [Fixed] `PicoDeprecated`: Sanitize `content_dir` and `base_url` options when reading `config.php` in Picos root dir * [Fixed] Replace `urldecode()` (deprecated RFC 1738) with `rawurldecode()` (RFC 3986) in `Page::evaluateRequestUrl()` * [Fixed] #272: Encode URLs using `rawurlencode()` in `Pico::getPageUrl()` * [Fixed] #274: Prevent double slashes in `base_url` +* [Fixed] #285: Make `index.php` work when installed as a composer dependency +* [Fixed] #291: Force `Pico::$requestUrl` to have no leading/trailing slash ``` ### Version 1.0.0-beta.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64e5f52..b849472 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,9 @@ Issues If you want to report an *issue* with Pico's core, please create a new [Issue](https://github.com/picocms/Pico/issues) on GitHub. Concerning problems with plugins or themes, please refer to the website of the developer of this plugin or theme. -Before creating a [new Issue on GitHub](https://github.com/picocms/Pico/issues/new), please make sure the problem wasn't reported yet using [GitHubs search engine](https://github.com/picocms/Pico/search?type=Issues). Please describe your issue as clear as possible and always include steps to reproduce the problem. +Before creating a [new Issue on GitHub](https://github.com/picocms/Pico/issues/new), please make sure the problem wasn't reported yet using [GitHubs search engine](https://github.com/picocms/Pico/search?type=Issues). + +Please describe your issue as clear as possible and always include the *Pico version* you're using. Provided that you're using *plugins*, include a list of them too. We need information about the *actual and expected behavior*, the *steps to reproduce* the problem, and what steps have you taken to resolve the problem by yourself (i.e. *your own troubleshooting*)? Contributing code ----------------- @@ -78,44 +80,18 @@ As soon as development reaches a point where feedback is appreciated, a pull req Build & Release process ----------------------- -This is work in progress. Please refer to [#268](https://github.com/picocms/Pico/issues/268) for details. +We're using [Travis CI](https://travis-ci.com) to automate the build & release process of Pico. It generates and deploys [phpDoc](http://phpdoc.org) class docs for new releases and on every commit to the `master` branch. Travis also prepares new releases by generating Pico's pre-built packages and uploading them to GitHub. Please refer to [our `.travis.yml`](https://github.com/picocms/Pico/blob/master/.travis.yml) for details. - +Travis CI will draft the new [release on GitHub](https://github.com/picocms/Pico/releases) automatically, but will require you to manually amend the descriptions formatting. The latest Pico version is always available at https://github.com/picocms/Pico/releases/latest, so please make sure to publish this URL rather than version-specific URLs. [Packagist](http://packagist.org/packages/picocms/pico) will be updated automatically. diff --git a/build/deploy-phpdoc-branch.sh b/build/deploy-phpdoc-branch.sh new file mode 100755 index 0000000..f08063d --- /dev/null +++ b/build/deploy-phpdoc-branch.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +if [ "$TRAVIS_PHP_VERSION" != "5.3" ]; then + echo "Skipping phpDoc deployment because this is not on the required runtime" + exit +fi + +if [[ ",$DEPLOY_PHPDOC_BRANCHES," != *,"$TRAVIS_BRANCH",* ]]; then + echo "Skipping phpDoc deployment because this branch ($TRAVIS_BRANCH) is not permitted to deploy" + exit +fi + +if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then + echo "Skipping phpDoc deployment because this pull request (#$TRAVIS_PULL_REQUEST) is not permitted to deploy" + exit +fi + +PHPDOC_ID="${TRAVIS_BRANCH//\//_}" + +generate-phpdoc.sh \ + "$TRAVIS_BUILD_DIR" "$TRAVIS_BUILD_DIR/build/phpdoc-$PHPDOC_ID" \ + "Pico 1.0 API Documentation ($TRAVIS_BRANCH branch)" +[ $? -eq 0 ] || exit 1 + +deploy-phpdoc.sh \ + "$TRAVIS_REPO_SLUG" "heads/$TRAVIS_BRANCH @ $TRAVIS_COMMIT" "$TRAVIS_BUILD_DIR/build/phpdoc-$PHPDOC_ID" \ + "$TRAVIS_REPO_SLUG" "gh-pages" "phpDoc/$PHPDOC_ID" +[ $? -eq 0 ] || exit 1 diff --git a/build/deploy-phpdoc-release.sh b/build/deploy-phpdoc-release.sh new file mode 100755 index 0000000..721f3a4 --- /dev/null +++ b/build/deploy-phpdoc-release.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +[ "$DEPLOY_PHPDOC_RELEASES" == "true" ] || exit + +PHPDOC_ID="${TRAVIS_BRANCH//\//_}" + +generate-phpdoc.sh \ + "$TRAVIS_BUILD_DIR" "$TRAVIS_BUILD_DIR/build/phpdoc-$PHPDOC_ID" \ + "Pico 1.0 API Documentation ($TRAVIS_TAG)" +[ $? -eq 0 ] || exit 1 + +deploy-phpdoc.sh \ + "$TRAVIS_REPO_SLUG" "tags/$TRAVIS_TAG" "$TRAVIS_BUILD_DIR/build/phpdoc-$PHPDOC_ID" \ + "$TRAVIS_REPO_SLUG" "gh-pages" "phpDoc/$PHPDOC_ID" +[ $? -eq 0 ] || exit 1 diff --git a/build/deploy-phpdoc.sh b/build/deploy-phpdoc.sh new file mode 100755 index 0000000..26d06b8 --- /dev/null +++ b/build/deploy-phpdoc.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +set -e + +# base variables +APP_NAME="$(basename "$0")" +BASE_PWD="$PWD" + +# environment variables +# GITHUB_OAUTH_TOKEN GitHub authentication token, see https://github.com/settings/tokens + +# parameters +SOURCE_REPO_SLUG="$1" # source GitHub repo (e.g. picocms/Pico) +SOURCE_REF="$2" # source reference (either "[ref] @ [commit]" or "[ref]", + # [ref] can be e.g. heads/master or tags/v1.0.0) +SOURCE_DIR="$3" # absolute source path +TARGET_REPO_SLUG="$4" # target GitHub repo (e.g. picocms/Pico) +TARGET_BRANCH="$5" # target branch (e.g. gh-pages) +TARGET_DIR="$6" # relative target path + +# print parameters +echo "Deploying phpDocs..." +printf 'SOURCE_REPO_SLUG="%s"\n' "$SOURCE_REPO_SLUG" +printf 'SOURCE_REF="%s"\n' "$SOURCE_REF" +printf 'SOURCE_DIR="%s"\n' "$SOURCE_DIR" +printf 'TARGET_REPO_SLUG="%s"\n' "$TARGET_REPO_SLUG" +printf 'TARGET_BRANCH="%s"\n' "$TARGET_BRANCH" +printf 'TARGET_DIR="%s"\n' "$TARGET_DIR" +echo + +# evaluate source reference +if [[ "$SOURCE_REF" == *" @ "* ]]; then + SOURCE_REF_TYPE="commit" + SOURCE_REF_HEAD="${SOURCE_REF% @ *}" + SOURCE_REF_COMMIT="${SOURCE_REF##* @ }" + + if ! git check-ref-format "$SOURCE_REF_HEAD" || ! git rev-parse --verify "$SOURCE_REF_COMMIT" > /dev/null; then + echo "FATAL: $APP_NAME source reference '$SOURCE_REF' is invalid" >&2 + exit 1 + fi +elif git check-ref-format "$SOURCE_REF"; then + SOURCE_REF_TYPE="ref" +else + echo "FATAL: $APP_NAME source reference '$SOURCE_REF' is invalid" >&2 + exit 1 +fi + +# clone repo +printf 'Cloning repo...\n' +GIT_DIR="$SOURCE_DIR.git" +git clone --branch="$TARGET_BRANCH" "https://github.com/$TARGET_REPO_SLUG.git" "$GIT_DIR" + +# setup git +cd "$GIT_DIR" +git config user.name "Travis CI" +git config user.email "travis-ci@picocms.org" + +if [ -n "$GITHUB_OAUTH_TOKEN" ]; then + git config credential.helper 'store --file=.git/credentials' + (umask 077 && echo "https://GitHub:$GITHUB_OAUTH_TOKEN@github.com" > .git/credentials) +fi + +# copy phpdoc +printf '\nCopying phpDocs...\n' +[ ! -d "$TARGET_DIR" ] || rm -rf "$TARGET_DIR" +[ "${SOURCE_DIR:0:1}" == "/" ] || SOURCE_DIR="$BASE_PWD/$SOURCE_DIR" +cp -R "$SOURCE_DIR" "$TARGET_DIR" + +# commit changes +printf '\nCommiting changes...\n' +git add --all "$TARGET_DIR" +git commit --message="Update phpDocumentor class docs for $SOURCE_REF" + +# very simple race condition protection for concurrent Travis builds +# this is no definite protection (race conditions are still possible during `git push`), +# but it should give a basic protection without disabling concurrent builds completely +if [ "$SOURCE_REF_TYPE" == "commit" ]; then + # load branch data via GitHub APIv3 + printf '\nRetrieving latest commit...\n' + LATEST_COMMIT_URL="https://api.github.com/repos/$SOURCE_REPO_SLUG/git/refs/$SOURCE_REF_HEAD" + if [ -n "$GITHUB_OAUTH_TOKEN" ]; then + LATEST_COMMIT_RESPONSE="$(wget -O- --header="Authorization: token $GITHUB_OAUTH_TOKEN" "$LATEST_COMMIT_URL" 2> /dev/null)" + else + LATEST_COMMIT_RESPONSE="$(wget -O- "$LATEST_COMMIT_URL" 2> /dev/null)" + fi + + # evaluate JSON response + LATEST_COMMIT="$(echo "$LATEST_COMMIT_RESPONSE" | php -r " + \$json = json_decode(stream_get_contents(STDIN), true); + if (\$json !== null) { + if (isset(\$json['ref']) && (\$json['ref'] === 'refs/$SOURCE_REF_HEAD')) { + if (isset(\$json['object']) && isset(\$json['object']['sha'])) { + echo \$json['object']['sha']; + } + } + } + ")" + + # compare source reference against the latest commit + if [ "$LATEST_COMMIT" != "$SOURCE_REF_COMMIT" ]; then + echo "WARNING: $APP_NAME source reference '$SOURCE_REF' doesn't match the latest commit '$LATEST_COMMIT'" >&2 + exit 0 + fi +fi + +# push changes +printf '\nPushing changes...\n' +git push "https://github.com/$TARGET_REPO_SLUG.git" "$TARGET_BRANCH:$TARGET_BRANCH" + +echo diff --git a/build/generate-phpdoc.sh b/build/generate-phpdoc.sh new file mode 100755 index 0000000..c2fe334 --- /dev/null +++ b/build/generate-phpdoc.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -e + +# parameters +PHPDOC_SOURCE_DIR="$1" +PHPDOC_TARGET_DIR="$2" +PHPDOC_TITLE="$3" + +# print parameters +echo "Generating phpDocs..." +printf 'PHPDOC_SOURCE_DIR="%s"\n' "$PHPDOC_SOURCE_DIR" +printf 'PHPDOC_TARGET_DIR="%s"\n' "$PHPDOC_TARGET_DIR" +printf 'PHPDOC_TITLE="%s"\n' "$PHPDOC_TITLE" +echo + +# generate phpdoc +phpdoc -d "$PHPDOC_SOURCE_DIR" \ + -i "$PHPDOC_SOURCE_DIR/build/" \ + -i "$PHPDOC_SOURCE_DIR/vendor/" \ + -i "$PHPDOC_SOURCE_DIR/plugins/" -f "$PHPDOC_SOURCE_DIR/plugins/DummyPlugin.php" \ + -t "$PHPDOC_TARGET_DIR" \ + --title "$PHPDOC_TITLE" + +echo diff --git a/composer.json b/composer.json index c8a1355..5894970 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,10 @@ "erusev/parsedown-extra": "^0.7", "symfony/yaml" : "^2.3" }, + "require-dev" : { + "phpdocumentor/phpdocumentor": "^2.8", + "squizlabs/php_codesniffer": "^2.4" + }, "autoload": { "psr-0": { "Pico": "lib/", diff --git a/content-sample/index.md b/content-sample/index.md index 55d385d..40abb8b 100644 --- a/content-sample/index.md +++ b/content-sample/index.md @@ -72,8 +72,8 @@ follows: !\[Image Title\](%base_url%/assets/image.png) Text files are marked up using [Markdown][]. They can also contain regular HTML. -At the top of text files you can place a block comment and specify certain -attributes of the page. For example: +At the top of text files you can place a block comment and specify certain meta +attributes of the page using [YAML][] (the "YAML header"). For example: --- Title: Welcome @@ -285,6 +285,7 @@ setting `$config['rewrite_url'] = true;` in your `config/config.php`. For more help have a look at the Pico documentation at http://picocms.org/docs. [Markdown]: http://daringfireball.net/projects/markdown/syntax +[YAML]: https://en.wikipedia.org/wiki/YAML [Twig]: http://twig.sensiolabs.org/documentation [WikiThemes]: https://github.com/picocms/Pico/wiki/Pico-Themes [WikiPlugins]: https://github.com/picocms/Pico/wiki/Pico-Plugins diff --git a/index.php b/index.php index 40b811a..7e7cdf0 100644 --- a/index.php +++ b/index.php @@ -1,6 +1,15 @@ -setConfig(array()); +//$pico->setConfig(array()); // run application echo $pico->run(); diff --git a/index.php.dist b/index.php.dist new file mode 100644 index 0000000..2186072 --- /dev/null +++ b/index.php.dist @@ -0,0 +1,20 @@ +run(); diff --git a/lib/Pico.php b/lib/Pico.php index 2a2a383..7f4b1c3 100644 --- a/lib/Pico.php +++ b/lib/Pico.php @@ -479,6 +479,10 @@ class Pico $this->config['base_url'] = rtrim($this->config['base_url'], '/') . '/'; } + if ($this->config['rewrite_url'] === null) { + $this->config['rewrite_url'] = $this->isUrlRewritingEnabled(); + } + if (empty($this->config['content_dir'])) { // try to guess the content directory if (is_dir($this->getRootDir() . 'content')) { @@ -563,9 +567,9 @@ class Pico * * We recommend you to use the `link` filter in templates to create * internal links, e.g. `{{ "sub/page"|link }}` is equivalent to - * `{{ base_url }}sub/page`. In content files you can still use the - * `%base_url%` variable; e.g. `%base_url%?sub/page` will be automatically - * replaced accordingly. + * `{{ base_url }}/sub/page` and `{{ base_url }}?sub/page`, depending on + * enabled URL rewriting. In content files you can use the `%base_url%` + * variable; e.g. `%base_url%?sub/page` will be replaced accordingly. * * @see Pico::getRequestUrl() * @return void @@ -583,6 +587,7 @@ class Pico $pathComponent = substr($pathComponent, 0, $pathComponentLength); } $this->requestUrl = (strpos($pathComponent, '=') === false) ? rawurldecode($pathComponent) : ''; + $this->requestUrl = trim($this->requestUrl, '/'); } /** @@ -934,7 +939,7 @@ class Pico $files = $this->getFiles($this->getConfig('content_dir'), $this->getConfig('content_ext'), Pico::SORT_NONE); foreach ($files as $i => $file) { // skip 404 page - if (basename($file) == '404' . $this->getConfig('content_ext')) { + if (basename($file) === '404' . $this->getConfig('content_ext')) { unset($files[$i]); continue; } @@ -972,7 +977,7 @@ class Pico 'meta' => &$meta ); - if ($file == $this->requestFile) { + if ($file === $this->requestFile) { $page['content'] = &$this->content; } @@ -1001,10 +1006,10 @@ class Pico $bSortKey = (basename($b['id']) === 'index') ? dirname($b['id']) : $b['id']; $cmp = strcmp($aSortKey, $bSortKey); - return $cmp * (($order == 'desc') ? -1 : 1); + return $cmp * (($order === 'desc') ? -1 : 1); }; - if ($this->getConfig('pages_order_by') == 'date') { + if ($this->getConfig('pages_order_by') === 'date') { // sort by date uasort($this->pages, function ($a, $b) use ($alphaSortClosure, $order) { if (empty($a['time']) || empty($b['time'])) { @@ -1018,7 +1023,7 @@ class Pico return $alphaSortClosure($a, $b); } - return $cmp * (($order == 'desc') ? 1 : -1); + return $cmp * (($order === 'desc') ? 1 : -1); }); } else { // sort alphabetically @@ -1031,7 +1036,7 @@ class Pico * * @see Pico::readPages() * @see Pico::sortPages() - * @return array|null the data of all pages + * @return array[]|null the data of all pages */ public function getPages() { @@ -1058,7 +1063,7 @@ class Pico if ($currentPageIndex !== false) { $this->currentPage = &$this->pages[$currentPageId]; - if (($this->getConfig('order_by') == 'date') && ($this->getConfig('order') == 'desc')) { + if (($this->getConfig('order_by') === 'date') && ($this->getConfig('order') === 'desc')) { $previousPageOffset = 1; $nextPageOffset = -1; } else { @@ -1198,7 +1203,7 @@ class Pico 'prev_page' => $this->previousPage, 'current_page' => $this->currentPage, 'next_page' => $this->nextPage, - 'is_front_page' => ($this->requestFile == $frontPage), + 'is_front_page' => ($this->requestFile === $frontPage), ); } @@ -1214,14 +1219,13 @@ class Pico return $baseUrl; } - if ( - (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') - || ($_SERVER['SERVER_PORT'] == 443) - || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') - ) { + $protocol = 'http'; + if (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] !== 'off')) { + $protocol = 'https'; + } elseif ($_SERVER['SERVER_PORT'] == 443) { + $protocol = 'https'; + } elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) { $protocol = 'https'; - } else { - $protocol = 'http'; } $this->config['base_url'] = @@ -1238,13 +1242,13 @@ class Pico */ public function isUrlRewritingEnabled() { - if (($this->getConfig('rewrite_url') === null) && isset($_SERVER['PICO_URL_REWRITING'])) { - return (bool) $_SERVER['PICO_URL_REWRITING']; - } elseif ($this->getConfig('rewrite_url')) { - return true; + $urlRewritingEnabled = $this->getConfig('rewrite_url'); + if ($urlRewritingEnabled !== null) { + return $urlRewritingEnabled; } - return false; + $this->config['rewrite_url'] = (isset($_SERVER['PICO_URL_REWRITING']) && $_SERVER['PICO_URL_REWRITING']); + return $this->getConfig('rewrite_url'); } /** diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..93b9ebb --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,39 @@ + + + + Pico's coding standards mainly base on the PHP-FIG PSR-2 standard, + but without the MissingNamespace sniff. + + + + ^build/ + ^vendor/ + *.min.js + + + + + + + + + + + + + + + + diff --git a/plugins/00-PicoDeprecated.php b/plugins/00-PicoDeprecated.php index 4866b9e..5240160 100644 --- a/plugins/00-PicoDeprecated.php +++ b/plugins/00-PicoDeprecated.php @@ -67,7 +67,7 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onPluginsLoaded() */ - public function onPluginsLoaded(&$plugins) + public function onPluginsLoaded(array &$plugins) { if (!empty($plugins)) { foreach ($plugins as $plugin) { @@ -107,19 +107,17 @@ class PicoDeprecated extends AbstractPicoPlugin * @see PicoDeprecated::loadRootDirConfig() * @see PicoDeprecated::enablePlugins() * @see DummyPlugin::onConfigLoaded() - * @param mixed[] &$realConfig array of config variables + * @param mixed[] &$config array of config variables * @return void */ - public function onConfigLoaded(&$realConfig) + public function onConfigLoaded(array &$config) { - global $config; - $this->defineConstants(); - $this->loadRootDirConfig($realConfig); + $this->loadRootDirConfig($config); $this->enablePlugins(); - $config = &$realConfig; + $GLOBALS['config'] = &$config; - $this->triggerEvent('config_loaded', array(&$realConfig)); + $this->triggerEvent('config_loaded', array(&$config)); } /** @@ -167,7 +165,7 @@ class PicoDeprecated extends AbstractPicoPlugin * @param mixed[] &$realConfig array of config variables * @return void */ - protected function loadRootDirConfig(&$realConfig) + protected function loadRootDirConfig(array &$realConfig) { if (file_exists($this->getRootDir() . 'config.php')) { // config.php in Pico::$rootDir is deprecated @@ -284,7 +282,7 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onMetaHeaders() */ - public function onMetaHeaders(&$headers) + public function onMetaHeaders(array &$headers) { $this->triggerEvent('before_read_file_meta', array(&$headers)); } @@ -294,7 +292,7 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onMetaParsed() */ - public function onMetaParsed(&$meta) + public function onMetaParsed(array &$meta) { $this->triggerEvent('file_meta', array(&$meta)); } @@ -328,7 +326,7 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onSinglePageLoaded() */ - public function onSinglePageLoaded(&$pageData) + public function onSinglePageLoaded(array &$pageData) { $this->triggerEvent('get_page_data', array(&$pageData, $pageData['meta'])); } @@ -344,8 +342,12 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onPagesLoaded() */ - public function onPagesLoaded(&$pages, &$currentPage, &$previousPage, &$nextPage) - { + public function onPagesLoaded( + array &$pages, + array &$currentPage = null, + array &$previousPage = null, + array &$nextPage = null + ) { // remove keys of pages array $plainPages = array(); foreach ($pages as &$pageData) { @@ -391,7 +393,7 @@ class PicoDeprecated extends AbstractPicoPlugin * * @see DummyPlugin::onPageRendering() */ - public function onPageRendering(&$twig, &$twigVariables, &$templateName) + public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName) { // template name contains file extension since Pico 1.0 $fileExtension = ''; diff --git a/plugins/01-PicoParsePagesContent.php b/plugins/01-PicoParsePagesContent.php index fd36f0a..db4ed10 100644 --- a/plugins/01-PicoParsePagesContent.php +++ b/plugins/01-PicoParsePagesContent.php @@ -30,7 +30,7 @@ class PicoParsePagesContent extends AbstractPicoPlugin * * @see DummyPlugin::onSinglePageLoaded() */ - public function onSinglePageLoaded(&$pageData) + public function onSinglePageLoaded(array &$pageData) { if (!isset($pageData['content'])) { $pageData['content'] = $this->prepareFileContent($pageData['raw_content'], $pageData['meta']); diff --git a/plugins/02-PicoExcerpt.php b/plugins/02-PicoExcerpt.php index 4ada382..7d0c449 100644 --- a/plugins/02-PicoExcerpt.php +++ b/plugins/02-PicoExcerpt.php @@ -40,7 +40,7 @@ class PicoExcerpt extends AbstractPicoPlugin * * @see DummyPlugin::onConfigLoaded() */ - public function onConfigLoaded(&$config) + public function onConfigLoaded(array &$config) { if (!isset($config['excerpt_length'])) { $config['excerpt_length'] = 50; @@ -53,7 +53,7 @@ class PicoExcerpt extends AbstractPicoPlugin * @see PicoExcerpt::createExcerpt() * @see DummyPlugin::onSinglePageLoaded() */ - public function onSinglePageLoaded(&$pageData) + public function onSinglePageLoaded(array &$pageData) { if (!isset($pageData['excerpt'])) { $pageData['excerpt'] = $this->createExcerpt( diff --git a/plugins/DummyPlugin.php b/plugins/DummyPlugin.php index 9ecd411..f8ebb01 100644 --- a/plugins/DummyPlugin.php +++ b/plugins/DummyPlugin.php @@ -11,7 +11,7 @@ * @license http://opensource.org/licenses/MIT * @version 1.0 */ -class DummyPlugin extends AbstractPicoPlugin +final class DummyPlugin extends AbstractPicoPlugin { /** * This plugin is enabled by default? @@ -40,7 +40,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param object[] &$plugins loaded plugin instances * @return void */ - public function onPluginsLoaded(&$plugins) + public function onPluginsLoaded(array &$plugins) { // your code } @@ -52,7 +52,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param mixed[] &$config array of config variables * @return void */ - public function onConfigLoaded(&$config) + public function onConfigLoaded(array &$config) { // your code } @@ -141,7 +141,7 @@ class DummyPlugin extends AbstractPicoPlugin * array key is later used to access the found value * @return void */ - public function onMetaHeaders(&$headers) + public function onMetaHeaders(array &$headers) { // your code } @@ -155,7 +155,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param string[] &$headers known meta header fields * @return void */ - public function onMetaParsing(&$rawContent, &$headers) + public function onMetaParsing(&$rawContent, array &$headers) { // your code } @@ -167,7 +167,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param string[] &$meta parsed meta data * @return void */ - public function onMetaParsed(&$meta) + public function onMetaParsed(array &$meta) { // your code } @@ -249,7 +249,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param array &$pageData data of the loaded page * @return void */ - public function onSinglePageLoaded(&$pageData) + public function onSinglePageLoaded(array &$pageData) { // your code } @@ -264,14 +264,18 @@ class DummyPlugin extends AbstractPicoPlugin * @see Pico::getCurrentPage() * @see Pico::getPreviousPage() * @see Pico::getNextPage() - * @param array &$pages data of all known pages - * @param array &$currentPage data of the page being served - * @param array &$previousPage data of the previous page - * @param array &$nextPage data of the next page + * @param array[] &$pages data of all known pages + * @param array|null &$currentPage data of the page being served + * @param array|null &$previousPage data of the previous page + * @param array|null &$nextPage data of the next page * @return void */ - public function onPagesLoaded(&$pages, &$currentPage, &$previousPage, &$nextPage) - { + public function onPagesLoaded( + array &$pages, + array &$currentPage = null, + array &$previousPage = null, + array &$nextPage = null + ) { // your code } @@ -295,7 +299,7 @@ class DummyPlugin extends AbstractPicoPlugin * @param string &$templateName file name of the template * @return void */ - public function onPageRendering(&$twig, &$twigVariables, &$templateName) + public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName) { // your code } diff --git a/themes/default/style.css b/themes/default/style.css new file mode 100644 index 0000000..d26f65a --- /dev/null +++ b/themes/default/style.css @@ -0,0 +1,367 @@ +/*=================================*/ +/* Pico Default Theme +/* By: Gilbert Pellegrom +/* http: //dev7studios.com +/*=================================*/ + +/* Reset Styles +/*---------------------------------------------*/ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +body { + line-height: 1; + color: black; + background: white; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +caption, th, td { + text-align: left; + font-weight: normal; +} + +blockquote:before, blockquote:after, +q:before, q:after { + content: ""; +} + +blockquote, q { + quotes: "" ""; +} + +/* HTML5 tags */ +header, section, footer, +aside, nav, article, figure { + display: block; +} + +/* hand cursor on clickable input elements */ +label, input[type=button], input[type=submit], button { + cursor: pointer; +} + +/* make buttons play nice in IE: + www.viget.com/inspire/styling-the-button-element-in-internet-explorer/ */ +button { + width: auto; + overflow: visible; +} + +/* Sharper Thumbnails */ +img { + -ms-interpolation-mode: bicubic; +} + +/* Input Styles +/*---------------------------------------------*/ +input, +textarea, +select { + padding: 5px; + font: 400 1em Verdana, Sans-serif; + color: #666; + background: #fff; + border: 1px solid #999999; + margin: 0 0 1em 0; +} + +input:focus, +textarea:focus, +select:focus { + color: #000; + background: #fff; + border: 1px solid #666666; +} + +/* Main Styles +/*---------------------------------------------*/ +body { + font: 14px/1.8em 'Open Sans', Helvetica, Arial, Helvetica, sans-serif; + color: #444; + background: #fff; + -webkit-font-smoothing: antialiased; +} + +a, a:visited { + color: #2EAE9B; + text-decoration: none; + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear; + -ms-transition: all 0.2s linear; + -o-transition: all 0.2s linear; + transition: all 0.2s linear; +} + +a:hover, a:active { + color: #000; + text-decoration: none; +} + +h1, h2, h3, h4, h5, h6 { + color: #000; + line-height: 1.2em; + margin-bottom: 0.6em; +} + +h1 { + font-size: 2em; +} + +h2 { + font-size: 1.7em; +} + +h3 { + font-size: 1.5em; + margin-top: 2em; +} + +p, table { + margin-bottom: 1em; +} + +ol, ul { + padding-left: 30px; + margin-bottom: 1em; +} + +b, strong { + font-weight: bold; +} + +i, em { + font-style: italic; +} + +u { + text-decoration: underline; +} + +abbr, acronym { + cursor: help; + border-bottom: 0.1em dotted; +} + +td, td img { + vertical-align: top; +} + +td, th { + border: solid 1px #999; + padding: 0.25em 0.5em; +} + +th { + font-weight: bold; + text-align: center; + background: #eee; +} + +sub { + vertical-align: sub; + font-size: smaller; +} + +sup { + vertical-align: super; + font-size: smaller; +} + +code { + font-family: Courier, "Courier New", Monaco, Tahoma; + background: #eee; + color: #333; + padding: 0px 2px; +} + +pre { + background: #eee; + padding: 20px; + margin-bottom: 1em; + overflow: auto; +} + +blockquote { + font-style: italic; + margin: 0 0 1em 15px; + padding-left: 10px; + border-left: 5px solid #dddddd; +} + +/* Structure Styles +/*---------------------------------------------*/ +.inner { + width: 850px; + margin: 0 auto; +} + +#header { + background: #2EAE9B; + padding: 60px 0; + margin-bottom: 80px; + color: #afe1da; +} +#header a { color: #afe1da; } +#header h1 a, +#header a:hover { color: #fff; } +#header h1 { + font-weight: bold; + margin: 0; + float: left; +} +#header .menu-icon { + display: none; + width: 35px; + height: 35px; + background: #afe1da url(menu-icon.png) center; +} +#header nav { + float: right; + list-style: none; + margin: 0; + padding: 0; +} +#header nav a { + font-weight: bold; + margin-left: 20px; +} +#header a:hover#menu-icon { + background-color: #444; + border-radius: 4px 4px 0 0; +} +#header ul { + list-style: none; +} +#header li { + display: inline-block; + float: left; +} +#footer { + background: #707070; + padding: 60px 0; + margin-top: 80px; + color: #C0C0C0; +} +#footer a { color: #ddd; } +#footer a:hover { color: #fff; } + +/* Misc Styles +/*---------------------------------------------*/ +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} +.clearfix:after { + clear: both; +} +.clearfix { + *zoom: 1; +} + +/* Media Queries +/*---------------------------------------------*/ + +/* Small Devices, Tablets */ +@media only screen and (max-width : 768px) { + .inner { + width: 85%; + } + .inner img { + width:100%; + } + #header { + margin-bottom: 40px; + } + #header h1 a { + font-size:1em; + } + #header .menu-icon { + display:inline-block; + } + #header nav a { color: #000; } + #header nav a:hover { color: #afe1da; } + #header nav ul, nav:active ul { + display: none; + position: absolute; + padding: 20px; + background: #fff; + border: 5px solid #444; + right: 2.7em; + top: 100px; + width: 80%; + border-radius: 4px 0 4px 4px; + z-index: 9999; + } + #header nav li { + text-align: center; + width: 100%; + padding: 10px 0; + margin: 0; + } + #header nav:hover ul { + display: block; + } +} + +/* Extra Small Devices, Phones */ +@media only screen and (max-width : 480px) { + .inner { + width: 85%; + } + .inner img { + width:100%; + } + #header { + margin-bottom: 30px; + } + #header h1 a { + font-size:1em; + } + #header .menu-icon { + display:inline-block; + } + #header nav a { color: #000; } + #header nav a:hover { color: #afe1da; } + #header nav ul, nav:active ul { + display: none; + position: absolute; + padding: 20px; + background: #fff; + border: 5px solid #444; + right: 0em; + top: 100px; + width: auto; + border-radius: 4px 0 4px 4px; + } + #header nav li { + text-align: center; + width: 100%; + padding: 10px 0; + margin: 0; + } + #header nav:hover ul { + display: block; + } +}