├── .codeclimate.yml ├── .gitignore ├── .php_cs ├── .travis.yml ├── .travis ├── test-reporter.sh └── travis.sh ├── CHANGELOG.md ├── CONTRIBUTORS.md ├── LICENSE ├── README.md ├── bin └── tapestry.php ├── box.json ├── build ├── .gitignore ├── BuildVersion.php └── tapestry.bat ├── composer.json ├── composer.lock ├── phpunit.xml ├── sami-config.php ├── src ├── ArrayContainer.php ├── Console │ ├── Application.php │ ├── Commands │ │ ├── BuildCommand.php │ │ ├── Command.php │ │ ├── InitCommand.php │ │ ├── SelfUpdateCommand.php │ │ └── ServeCommand.php │ ├── DefaultInputDefinition.php │ └── Input.php ├── Entities │ ├── Cache.php │ ├── CacheStore.php │ ├── CachedFile.php │ ├── Collections │ │ ├── Collection.php │ │ ├── ExcludedFilesCollection.php │ │ └── FlatCollection.php │ ├── Configuration.php │ ├── ContentType.php │ ├── File.php │ ├── Filesystem │ │ ├── FileAction.php │ │ ├── FileCopier.php │ │ ├── FileIgnored.php │ │ ├── FileWriter.php │ │ └── FilesystemInterface.php │ ├── Generators │ │ ├── CollectionItemGenerator.php │ │ ├── FileGenerator.php │ │ ├── PaginationGenerator.php │ │ ├── TaxonomyArchiveGenerator.php │ │ └── TaxonomyIndexGenerator.php │ ├── Pagination.php │ ├── Permalink.php │ ├── Project.php │ ├── ProjectFileGeneratorInterface.php │ ├── ProjectFileInterface.php │ ├── Renderers │ │ ├── DefaultRenderer.php │ │ ├── HTMLRenderer.php │ │ ├── MarkdownRenderer.php │ │ ├── PlatesRenderer.php │ │ └── RendererInterface.php │ ├── Taxonomy.php │ ├── Url.php │ ├── ViewFile.php │ └── ViewFileTrait.php ├── Exceptions │ ├── InvalidConsoleInputException.php │ ├── InvalidCurrentWorkingDirectoryException.php │ ├── InvalidVersionException.php │ └── LockException.php ├── Generator.php ├── Modules │ ├── Api │ │ └── Json.php │ ├── Config │ │ └── DefaultConfig.php │ ├── Content │ │ ├── Clean.php │ │ ├── Clear.php │ │ ├── Compile.php │ │ ├── Copy.php │ │ ├── FrontMatter.php │ │ ├── LoadSourceFiles.php │ │ ├── ReadCache.php │ │ ├── WriteCache.php │ │ └── WriteFiles.php │ ├── ContentTypes │ │ ├── ContentTypeFactory.php │ │ ├── LoadContentTypes.php │ │ └── ParseContentTypes.php │ ├── Generators │ │ ├── ContentGeneratorFactory.php │ │ └── LoadContentGenerators.php │ ├── Kernel │ │ ├── BootKernel.php │ │ ├── DefaultKernel.php │ │ └── KernelInterface.php │ ├── Renderers │ │ ├── ContentRendererFactory.php │ │ └── LoadContentRenderers.php │ └── Scripts │ │ ├── After.php │ │ ├── Before.php │ │ └── Script.php ├── Plates │ ├── Engine.php │ ├── Extensions │ │ ├── Environment.php │ │ ├── Helpers.php │ │ ├── Site.php │ │ └── Url.php │ └── Template.php ├── Profiler.php ├── Providers │ ├── CommandServiceProvider.php │ ├── CompileStepsServiceProvider.php │ ├── PlatesServiceProvider.php │ ├── ProjectConfigurationServiceProvider.php │ ├── ProjectKernelServiceProvider.php │ └── ProjectServiceProvider.php ├── Scaffold │ ├── .gitignore │ ├── config.php │ ├── gulpfile.js │ ├── kernel.php │ ├── package.json │ └── source │ │ ├── _assets │ │ ├── img │ │ │ └── favicon.ico │ │ ├── js │ │ │ └── app.js │ │ └── less │ │ │ └── main.less │ │ ├── _blog │ │ └── 2016-01-01-hello-world.md │ │ ├── _templates │ │ └── default.phtml │ │ ├── _views │ │ └── blog.phtml │ │ └── index.phtml ├── Step.php ├── Tapestry.php ├── Version.php ├── bootstrap.php └── helpers.php └── tests ├── .gitkeep ├── ArrayContainerMergeTest.php ├── BuildCommandTest.php ├── CacheTest.php ├── CollectionsTest.php ├── CommandLineApplicationTest.php ├── CommandTestBase.php ├── ConfigurationTest.php ├── ContentTypeTest.php ├── CopyTest.php ├── EntitiesTest.php ├── FileTest.php ├── FrontmatterTest.php ├── HelpersTest.php ├── JsonApiTest.php ├── KernelTest.php ├── LockFileTest.php ├── MarkdownLayoutTest.php ├── MockArrayAccessByKeyClass.php ├── Mocks ├── TaxonomyMocks │ ├── 2016-01-01-a.md │ ├── 2016-01-02-b.md │ ├── 2016-01-03-c.md │ ├── 2016-01-04-d.md │ ├── 2016-01-05-e.md │ └── 2016-01-05-f.md ├── TestCategoryPermalinkTag.md ├── TestEnvironmentFile.phtml ├── TestExcerptFile.md ├── TestFile.md ├── TestFileNoBody.md ├── TestPaginatorFile.phtml └── TestPaginatorSkipFile.phtml ├── PaginationGeneratorTest.php ├── PaginationTest.php ├── PermalinkTest.php ├── PlatesExtensionsTest.php ├── RendererTest.php ├── StopwatchProfilerTest.php ├── TaxonomyArchiveGeneratorTest.php ├── TaxonomyTest.php ├── Traits ├── MockFile.php ├── MockTapestry.php └── MockViewFile.php ├── UnPublishDraftsTest.php ├── ViewFileTraitTest.php ├── assets ├── build_test_1 │ ├── check │ │ ├── about.html │ │ └── index.html │ └── src │ │ ├── config.php │ │ ├── kernel.php │ │ └── source │ │ ├── about.md │ │ ├── assets │ │ └── js │ │ │ └── app.js │ │ └── index.phtml ├── build_test_10 │ └── src │ │ ├── TestKernelCommand.php │ │ ├── config.php │ │ └── kernel.php ├── build_test_11 │ ├── check │ │ └── blog │ │ │ └── 2016 │ │ │ ├── test-blog-entry-two.html │ │ │ └── test-blog-entry.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2016-03-10-test-blog-entry.md │ │ └── 2016-03-11-test-blog-entry-two.md │ │ ├── _templates │ │ └── default.phtml │ │ ├── _views │ │ └── blog.phtml │ │ └── index.html ├── build_test_12 │ ├── check │ │ └── blog │ │ │ └── 2016 │ │ │ └── test-blog-entry.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2016-03-10-test-blog-entry.md │ │ ├── 2016-03-11-test-blog-entry-two.md │ │ └── 2116-03-11-test-blog-entry-three.md │ │ ├── _views │ │ └── blog.phtml │ │ └── index.html ├── build_test_13 │ ├── check │ │ └── blog │ │ │ └── 2016 │ │ │ ├── test-blog-entry-two.html │ │ │ └── test-blog-entry.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2016-03-10-test-blog-entry.md │ │ └── 2016-03-11-test-blog-entry-two.md │ │ ├── _views │ │ └── blog.phtml │ │ └── index.html ├── build_test_14 │ ├── check │ │ ├── default_index.html │ │ └── development_index.html │ └── src │ │ ├── config-development.php │ │ ├── config.php │ │ └── source │ │ └── index.phtml ├── build_test_15 │ ├── check │ │ ├── draft-false.html │ │ └── draft-true.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── draft-false.phtml │ │ └── draft-true.phtml ├── build_test_16 │ ├── check │ │ └── index.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2015-08-22-first-post.md │ │ └── 2016-08-22-no-categories.md │ │ └── index.phtml ├── build_test_17 │ ├── check │ │ ├── 1.html │ │ └── 2.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2015-08-22-first-post.md │ │ ├── 2015-08-23-second-post.md │ │ ├── 2015-08-24-third-post.md │ │ └── 2015-08-25-fourth-post.md │ │ ├── blog │ │ └── index.phtml │ │ └── index.phtml ├── build_test_18 │ ├── check │ │ ├── first-post.html │ │ ├── fourth-post.html │ │ ├── second-post.html │ │ └── third-post.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2015-08-22-first-post.md │ │ ├── 2015-08-23-second-post.md │ │ ├── 2015-08-24-third-post.md │ │ └── 2015-08-25-fourth-post.md │ │ ├── _views │ │ └── blog.phtml │ │ ├── blog │ │ └── index.phtml │ │ └── index.phtml ├── build_test_19 │ ├── check │ │ └── test.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _templates │ │ └── page.phtml │ │ └── test.md ├── build_test_2 │ ├── check │ │ ├── about.html │ │ └── index.phtml │ └── src │ │ ├── config.php │ │ ├── kernel.php │ │ └── source │ │ ├── about.md │ │ ├── assets │ │ └── js │ │ │ └── app.js │ │ └── index.phtml ├── build_test_20 │ ├── check │ │ └── test.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _templates │ │ ├── child.phtml │ │ └── page.phtml │ │ └── test.md ├── build_test_21 │ ├── src │ │ ├── config.php │ │ └── kernel.php │ └── src_replace │ │ ├── config.php │ │ └── kernel.php ├── build_test_22 │ ├── check │ │ ├── index.html │ │ ├── index_replace.html │ │ └── multi-inheritance.html │ ├── src │ │ ├── config.php │ │ └── source │ │ │ ├── _templates │ │ │ ├── inheritance-test.phtml │ │ │ └── page.phtml │ │ │ ├── multi-inheritance-test.md │ │ │ └── test.md │ └── src_replace │ │ └── page.phtml ├── build_test_23 │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2015-08-22-first-post.md │ │ ├── 2015-08-23-second-post.md │ │ ├── 2015-08-24-third-post.md │ │ └── 2015-08-25-fourth-post.md │ │ ├── blog │ │ └── categories │ │ │ └── category.phtml │ │ └── index.phtml ├── build_test_24 │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ ├── 2015-08-22-first-post.md │ │ ├── 2015-08-23-second-post.md │ │ ├── 2015-08-24-third-post.md │ │ └── 2015-08-25-fourth-post.md │ │ ├── blog │ │ └── categories │ │ │ └── category.phtml │ │ └── index.phtml ├── build_test_25 │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ └── 2015-08-22-first-post.md │ │ └── index.phtml ├── build_test_26 │ ├── check │ │ ├── development_index.html │ │ └── index.html │ └── src │ │ ├── config-development.yaml │ │ ├── config.yaml │ │ └── source │ │ └── index.phtml ├── build_test_27 │ ├── check │ │ ├── development_index.html │ │ └── index.html │ └── src │ │ ├── config-development.php │ │ ├── config-development.yaml │ │ ├── config.php │ │ ├── config.yaml │ │ └── source │ │ └── index.phtml ├── build_test_28 │ ├── check │ │ └── index.html │ └── src │ │ ├── config.php │ │ ├── kernel.php │ │ ├── lib │ │ └── TestPlatesExtension.php │ │ └── source │ │ └── index.phtml ├── build_test_29 │ ├── check │ │ └── index.html │ └── src │ │ ├── config.php │ │ └── source │ │ └── index.php ├── build_test_3 │ ├── check │ │ ├── about.html │ │ ├── index.html │ │ └── not-pretty.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── about.md │ │ ├── index.md │ │ └── not-pretty.md ├── build_test_30 │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _should-not-exist │ │ └── index.html │ │ ├── index.php │ │ └── should-exist │ │ ├── _should-not-exist │ │ └── index.html │ │ └── index.html ├── build_test_31 │ ├── check │ │ ├── base.html │ │ ├── blog.html │ │ ├── page-multi.html │ │ ├── page.html │ │ └── single.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ └── 2016-04-18-test.md │ │ ├── _templates │ │ ├── default.phtml │ │ └── page.phtml │ │ ├── _views │ │ └── blog.phtml │ │ ├── base.phtml │ │ ├── page-multi.md │ │ ├── page.md │ │ └── single.phtml ├── build_test_32 │ └── src │ │ ├── config.php │ │ └── source │ │ └── index.phtml ├── build_test_33 │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _blog │ │ └── 2016-04-18-test.md │ │ ├── _templates │ │ └── default.phtml │ │ └── _views │ │ └── blog.phtml ├── build_test_34 │ └── src │ │ └── source │ │ ├── _templates │ │ └── test-template.phtml │ │ └── test.html ├── build_test_35 │ └── src │ │ └── source │ │ ├── abc.123.xyz.html │ │ └── css │ │ └── main.min.css ├── build_test_36 │ └── src │ │ └── source │ │ ├── file-a.phtml │ │ └── file-b.phtml ├── build_test_37 │ └── src │ │ ├── config.php │ │ └── kernel.php ├── build_test_38 │ └── src │ │ ├── Kernel.php │ │ └── config.php ├── build_test_39 │ └── src │ │ └── source │ │ ├── default.css │ │ ├── default.min.css │ │ └── default.min.css.map ├── build_test_4 │ ├── check │ │ ├── about.html │ │ └── index.html │ └── src │ │ ├── config.php │ │ └── source │ │ ├── _templates │ │ └── default.phtml │ │ ├── about.md │ │ ├── assets │ │ └── js │ │ │ ├── app.js │ │ │ └── something_else │ │ │ ├── a.js │ │ │ └── b.js │ │ ├── ignored_folder │ │ └── should_be_ignored.md │ │ └── index.php ├── build_test_40 │ └── src │ │ ├── config.php │ │ └── source │ │ └── index.phtml ├── build_test_5 │ ├── check │ │ ├── about.html │ │ └── index.html │ └── src │ │ └── source │ │ ├── a_folder │ │ ├── a_file.md │ │ ├── another_file.md │ │ └── b_folder │ │ │ └── b_file.md │ │ ├── about.md │ │ ├── b_folder │ │ ├── b_file_2.md │ │ └── b_file_3.md │ │ └── index.php ├── build_test_6 │ ├── check │ │ └── index.html │ └── src │ │ └── source │ │ ├── _templates │ │ └── default.phtml │ │ └── index.phtml ├── build_test_7 │ └── src │ │ └── source │ │ ├── aaa.md │ │ ├── blog.md │ │ ├── else.md │ │ ├── index.html │ │ ├── something.html │ │ └── testy.md ├── build_test_8 │ ├── check │ │ ├── boot.html │ │ └── register.html │ └── src │ │ ├── config.php │ │ ├── kernel.php │ │ └── source │ │ ├── boot.phtml │ │ └── register.phtml └── cache_files │ ├── .local_cache.1.0.10 │ ├── .local_cache.1.0.8 │ └── .local_cache.1.0.9 └── mocks ├── TestCategoryPermalinkTagLimitOne.md └── TestCategoryPermalinkTagLimitTwo.md /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | duplication: 3 | enabled: true 4 | config: 5 | languages: 6 | - php 7 | fixme: 8 | enabled: true 9 | phpmd: 10 | enabled: true 11 | checks: 12 | CleanCode/ElseExpression: 13 | enabled: false 14 | Controversial/Superglobals: 15 | enabled: false 16 | phpcodesniffer: 17 | enabled: true 18 | ratings: 19 | paths: 20 | - "**.php" 21 | exclude_paths: 22 | - tests/ 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | box.phar 4 | sami.phar 5 | vendor 6 | bin/tapestry.phar 7 | bin/tapestry.version 8 | src/build.json -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | finder(DefaultFinder::create()->in(__DIR__)) 75 | ->fixers($fixers) 76 | ->level(FixerInterface::NONE_LEVEL) 77 | ->setUsingCache(true); -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | sudo: false 4 | 5 | matrix: 6 | include: 7 | - php: 5.6 8 | - php: 7.0 9 | - php: 7.1 10 | env: WITH_COVERAGE=true 11 | - php: nightly 12 | allow_failures: 13 | - php: nightly 14 | fast_finish: true 15 | 16 | cache: 17 | directories: 18 | - $HOME/.composer/cache 19 | 20 | before_install: 21 | - source .travis/travis.sh 22 | - source .travis/test-reporter.sh 23 | - xdebug-disable 24 | - travis_retry composer self-update 25 | 26 | install: 27 | - travis_retry composer install --no-interaction --prefer-dist --no-suggest; 28 | 29 | script: 30 | - mkdir -p build/logs 31 | - run-tests 32 | 33 | before_script: 34 | - codeclimate-before-build 35 | 36 | after_success: 37 | - codeclimate-after-build 38 | 39 | -------------------------------------------------------------------------------- /.travis/test-reporter.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This file provides some helper functions for the use of code climates test coverage reporter 4 | # with Travis. 5 | # 6 | # More information: https://docs.codeclimate.com/docs/travis-ci-test-coverage 7 | 8 | function codeclimate-before-build() { 9 | if [[ "$WITH_COVERAGE" == "true" ]]; then 10 | curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > $TRAVIS_BUILD_DIR/cc-test-reporter 11 | chmod +x $TRAVIS_BUILD_DIR/cc-test-reporter 12 | $TRAVIS_BUILD_DIR/cc-test-reporter before-build 13 | fi 14 | } 15 | 16 | function codeclimate-after-build() { 17 | if [[ "$WITH_COVERAGE" == "true" ]]; then 18 | if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then 19 | $TRAVIS_BUILD_DIR/cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT 20 | fi 21 | fi 22 | } -------------------------------------------------------------------------------- /.travis/travis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # The problem is that we do not want to remove the configuration file, just disable it for a few tasks, then enable it 4 | # 5 | # For reference, see 6 | # 7 | # - https://docs.travis-ci.com/user/languages/php#Disabling-preinstalled-PHP-extensions 8 | # - https://docs.travis-ci.com/user/languages/php#Custom-PHP-configuration 9 | # 10 | # Original Source (this was copied from): 11 | # - https://github.com/codeclimate/php-test-reporter/blob/master/.travis/travis.sh 12 | 13 | config="/home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini" 14 | 15 | function xdebug-disable() { 16 | if [[ -f $config ]]; then 17 | mv $config "$config.bak" 18 | fi 19 | } 20 | 21 | function xdebug-enable() { 22 | if [[ -f "$config.bak" ]]; then 23 | mv "$config.bak" $config 24 | fi 25 | } 26 | 27 | function run-tests() { 28 | if [[ "$WITH_COVERAGE" == "true" ]]; then 29 | xdebug-enable 30 | vendor/bin/phpunit --coverage-clover=$TRAVIS_BUILD_DIR/build/logs/clover.xml 31 | xdebug-disable 32 | else 33 | vendor/bin/phpunit 34 | fi 35 | } -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributions to Tapestry 2 | 3 | ## Creator & Maintainer 4 | 5 | * Simon Dann 6 | 7 | ## Contributors 8 | 9 | In chronological order: 10 | 11 | * [Your name or handle] <[email or website]> 12 | * [Brief summary of your changes] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Simon Dann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Tapestry

2 |

Plates PHP Static Site Generator

3 | 4 |

5 | Build Status 6 | Test Coverage 7 | Latest Stable Version 8 | License 9 |

10 | 11 | ## About Tapestry 12 | Tapestry is a static site generator that uses the [plates](http://platesphp.com/) template system by the league of extraordinary packages. Tapestry aims to be fast, easy to use and easy to extend. It has been inspired by similar generators [Sculpin](https://sculpin.io/) and [Jigsaw](http://jigsaw.tighten.co/). Tapestry is designed for developers who prefer to use native PHP templates over compiled template languages such as Twig or Blade. 13 | 14 | ### Highlights 15 | * Native PHP templates with the use of the [plates](http://platesphp.com/) template system 16 | * [Blog aware](https://www.tapestry.cloud/documentation/your-content/) out of the box 17 | * Built to be extendable with [plugins](https://www.tapestry.cloud/documentation/working-examples/#plugins) 18 | 19 | ## Learning Tapestry 20 | The [Tapestry documentation](https://www.tapestry.cloud/documentation/?utm_source=github&utm_medium=referral&utm_campaign=README) provides a thorough insight into the inner workings of Tapestry. Making it as easy as possible to get started generating your sites. 21 | 22 | ## Installing Tapestry 23 | The recommended method for installing Tapestry is to grab the latest [zipped release here](https://github.com/carbontwelve/tapestry/releases) and unzip the contents into your `$PATH` to make it globally available from your command line. 24 | 25 | For Windows environments a `.bat` file is included so that you do not have to type `php tapestry.phar` to run Tapestry; for it to work ensure it is kept in the same folder as the `.phar`. 26 | 27 | For alternative methods of installing Tapestry see the [install documentation here](https://www.tapestry.cloud/documentation/installation/?utm_source=github&utm_medium=referral&utm_campaign=README). 28 | 29 | ## License 30 | Tapestry is open sourced software licensed under the [MIT License](LICENSE). 31 | 32 | ## Not invented here 33 | [StaticGen](https://www.staticgen.com/) has a list of other static site generators available, although to my knowledge Tapestry is the only one to use the PHPPlates template engine. 34 | -------------------------------------------------------------------------------- /bin/tapestry.php: -------------------------------------------------------------------------------- 1 | run(); 22 | } catch (\Exception $e) { 23 | echo 'Uncaught Exception '.get_class($e).' with message: '.$e->getMessage().PHP_EOL; 24 | echo $e->getTraceAsString(); 25 | exit(1); 26 | } 27 | -------------------------------------------------------------------------------- /box.json: -------------------------------------------------------------------------------- 1 | { 2 | "chmod": "0755", 3 | "compression": "GZ", 4 | "alias": "tapestry.phar", 5 | "directories": [ 6 | "src" 7 | ], 8 | "compactors": [ 9 | "Herrera\\Box\\Compactor\\Php" 10 | ], 11 | "extract": false, 12 | "intercept": true, 13 | "files": [ 14 | "LICENSE" 15 | ], 16 | "finder": [ 17 | { 18 | "name": [ 19 | "*.php", 20 | "*.pem" 21 | ], 22 | "exclude": [ 23 | "bin", 24 | "tests", 25 | "Tests" 26 | ], 27 | "in": [ 28 | "vendor" 29 | ] 30 | } 31 | ], 32 | "git-version": "package_version", 33 | "main": "bin/tapestry.php", 34 | "metadata": "Tapestry Static Site Generator", 35 | "output": "build/tapestry.phar", 36 | "shebang": "#!/usr/bin/env php", 37 | "stub": true 38 | } -------------------------------------------------------------------------------- /build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.bat 3 | !.gitignore 4 | !BuildVersion.php -------------------------------------------------------------------------------- /build/BuildVersion.php: -------------------------------------------------------------------------------- 1 | exec('git rev-parse --short --verify HEAD'), 7 | 'date' => date('c'), 8 | ]); 9 | 10 | file_put_contents(__DIR__.'/../src/build.json', $json); 11 | -------------------------------------------------------------------------------- /build/tapestry.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | php "%~dp0tapestry.phar" %* 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tapestry-cloud/tapestry", 3 | "description": "Static site generator with PHPPlates", 4 | "keywords": [ 5 | "plates", 6 | "static", 7 | "site", 8 | "generator" 9 | ], 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Simon Dann", 14 | "email": "simon.dann@gmail.com" 15 | } 16 | ], 17 | "autoload": { 18 | "psr-4": { 19 | "Tapestry\\": "src" 20 | }, 21 | "files": [ 22 | "src/helpers.php" 23 | ] 24 | }, 25 | "autoload-dev": { 26 | "psr-4": { 27 | "Tapestry\\Tests\\": "tests" 28 | } 29 | }, 30 | "require": { 31 | "php": ">=5.6.0", 32 | "symfony/console": "^3.1", 33 | "symfony/filesystem": "^3.1", 34 | "symfony/finder" : "^3.1", 35 | "symfony/yaml": "^3.1", 36 | "league/container": "^2.2", 37 | "league/plates": "^3.1", 38 | "league/event": "^2.1", 39 | "nesbot/carbon": "^1.21", 40 | "composer/semver": "^1.4", 41 | "michelf/php-markdown": "^1.7", 42 | "symfony/process": "^3.4" 43 | }, 44 | "require-dev": { 45 | "phpunit/phpunit": "5.7.*" 46 | }, 47 | "bin": [ 48 | "bin/tapestry.php" 49 | ], 50 | "scripts": { 51 | "box": [ 52 | "composer install --no-dev --prefer-dist", 53 | "@php -r \"file_exists('box.phar') || exec('curl -LSs https://box-project.github.io/box2/installer.php | php');\"", 54 | "@php build/BuildVersion.php", 55 | "@php box.phar build -v" 56 | ], 57 | "api-docs": [ 58 | "@php -r \"file_exists('sami.phar') || exec('curl -O http://get.sensiolabs.org/sami.phar');\"", 59 | "@php sami.phar update sami-config.php" 60 | ] 61 | }, 62 | "extra": { 63 | "branch-alias": { 64 | "dev-master": "1.1.0-dev" 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ./tests/ 23 | 24 | 25 | 26 | 27 | 28 | ./src 29 | 30 | ./tests 31 | ./vendor 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /sami-config.php: -------------------------------------------------------------------------------- 1 | addFromTags('1.0.*') 11 | ->add('2.0.0-dev', '2.0.0 dev-branch') 12 | ->add('master', 'master branch'); 13 | 14 | return new Sami($dir, [ 15 | 'versions' => $versions, 16 | 'title' => 'Tapestry API', 17 | 'build_dir' => __DIR__.'/build/docs/%version%', 18 | 'cache_dir' => __DIR__.'/build/cache/%version%', 19 | 'remote_repository' => new GitHubRemoteRepository('tapestry-cloud/tapestry', dirname($dir)), 20 | 'default_opened_level' => 2, 21 | ]); 22 | -------------------------------------------------------------------------------- /src/Console/Application.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 26 | $this->addCommands($commands); 27 | } 28 | 29 | protected function getDefaultInputDefinition() 30 | { 31 | return new DefaultInputDefinition(); 32 | } 33 | 34 | /** 35 | * Returns the long version of the application. 36 | * 37 | * @return string The long application version 38 | */ 39 | public function getLongVersion() 40 | { 41 | if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { 42 | return sprintf('%s version %s, environment %s', 43 | $this->getName(), $this->getVersion(), $this->tapestry['environment']); 44 | } 45 | 46 | return 'Console Tool'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Console/Commands/BuildCommand.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 33 | $this->steps = $steps; 34 | } 35 | 36 | /** 37 | * @return void 38 | */ 39 | protected function configure() 40 | { 41 | $this->setName('build') 42 | ->setDescription('Build Project.'); 43 | 44 | $this->getDefinition()->addOptions( 45 | [ 46 | new InputOption('--clear', null, InputOption::VALUE_NONE, 'Clear the destination path and disable caching.'), 47 | new InputOption('--json', false, InputOption::VALUE_NONE, 'Output a json file containing the current build state.'), 48 | new InputOption('--no-write', false, InputOption::VALUE_NONE, 'When set Tapestry will build the state but not commit to the file system.'), 49 | new InputOption('--auto-publish', false, InputOption::VALUE_NONE, 'Set Tapestry to consider draft posts with a date <= now as scheduled.'), 50 | ] 51 | ); 52 | } 53 | 54 | protected function fire() 55 | { 56 | try { 57 | $this->tapestry->setInput($this->input); 58 | $this->tapestry->setOutput($this->output); 59 | $this->tapestry->validateInput(); 60 | } catch (InvalidConsoleInputException $e) { 61 | $this->output->writeln('[!] '.$e->getMessage().' Doing nothing and exiting.'); 62 | 63 | return 1; 64 | } 65 | 66 | $generator = new Generator($this->steps, $this->tapestry); 67 | 68 | /** @var Project $project */ 69 | $project = $this->tapestry->getContainer()->get(Project::class); 70 | 71 | return $generator->generate($project, $this->output); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Console/DefaultInputDefinition.php: -------------------------------------------------------------------------------- 1 | path = $path; 36 | $this->hash = $hash; 37 | $this->store = new CacheStore($this->hash, Tapestry::VERSION); 38 | } 39 | 40 | public function load() 41 | { 42 | if (file_exists($this->path)) { 43 | $this->store = unserialize(file_get_contents($this->path)); 44 | $this->store->validate($this->hash); 45 | if (is_null($this->store->getTapestryVersion())) { 46 | $this->store->setTapestryVersion(Tapestry::VERSION); 47 | } else { 48 | // If Tapestry version is older than that used to generate the project then throw an error. 49 | // Else update the stored tapestry version. 50 | if (Comparator::greaterThan($this->store->getTapestryVersion(), Tapestry::VERSION)) { 51 | throw new InvalidVersionException('This project was last generated with Tapestry version ['.$this->store->getTapestryVersion().'], you are compiling with an outdated version.'); 52 | } else { 53 | $this->store->setTapestryVersion(Tapestry::VERSION); 54 | } 55 | } 56 | } 57 | } 58 | 59 | public function save() 60 | { 61 | file_put_contents($this->path, serialize($this->store)); 62 | } 63 | 64 | public function setCacheStore(CacheStore $cacheStore) 65 | { 66 | $this->store = $cacheStore; 67 | } 68 | 69 | public function setItem($key, $value) 70 | { 71 | $this->store->setItem($key, $value); 72 | } 73 | 74 | public function getItem($key) 75 | { 76 | return $this->store->getItem($key); 77 | } 78 | 79 | public function count() 80 | { 81 | return $this->store->count(); 82 | } 83 | 84 | public function reset() 85 | { 86 | $this->store->reset(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Entities/CacheStore.php: -------------------------------------------------------------------------------- 1 | setTapestryVersion($version); 37 | $this->hash = $hash; 38 | } 39 | 40 | /** 41 | * Reset the cache store if $hash is different to the one in the store. 42 | * 43 | * @param $hash 44 | */ 45 | public function validate($hash) 46 | { 47 | if ($hash !== $this->hash) { 48 | $this->reset(); 49 | } 50 | } 51 | 52 | public function setTapestryVersion($version) 53 | { 54 | $this->version = $version; 55 | } 56 | 57 | public function getTapestryVersion() 58 | { 59 | return $this->version; 60 | } 61 | 62 | public function setItem($key, $value) 63 | { 64 | $this->items[$key] = $value; 65 | } 66 | 67 | public function getItem($key) 68 | { 69 | if (isset($this->items[$key])) { 70 | return $this->items[$key]; 71 | } 72 | 73 | return null; 74 | } 75 | 76 | public function count() 77 | { 78 | return count($this->items); 79 | } 80 | 81 | public function reset() 82 | { 83 | $this->items = []; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Entities/CachedFile.php: -------------------------------------------------------------------------------- 1 | layouts = $layouts; 41 | $this->sourceDirectory = $sourceDirectory; 42 | $this->uid = $file->getUid(); 43 | $this->hash = $this->hashFile($file); 44 | } 45 | 46 | /** 47 | * Check to see if the current cache entry is still valid. 48 | * 49 | * @param File $file 50 | * @return bool 51 | * @throws \Exception 52 | */ 53 | public function check(File $file) 54 | { 55 | if ($file->getUid() !== $this->uid) { 56 | throw new \Exception('This CachedFile is not for uid ['.$file->getUid().']'); 57 | } 58 | 59 | return $this->hash === $this->hashFile($file); 60 | } 61 | 62 | /** 63 | * Calculates the invalidation hash for the given File. 64 | * 65 | * @param File $file 66 | * @return string 67 | */ 68 | private function hashFile(File $file) 69 | { 70 | $arr = []; 71 | 72 | foreach ($this->layouts as $layout) { 73 | if (strpos($layout, '_templates') === false) { 74 | $layout = '_templates'.DIRECTORY_SEPARATOR.$layout; 75 | } 76 | 77 | $layoutPathName = $this->sourceDirectory.DIRECTORY_SEPARATOR.$layout.'.phtml'; 78 | if (file_exists($layoutPathName)) { 79 | array_push($arr, sha1_file($layoutPathName)); 80 | } 81 | } 82 | 83 | array_push($arr, $file->getLastModified()); 84 | 85 | return sha1(implode('.', $arr)); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Entities/Collections/Collection.php: -------------------------------------------------------------------------------- 1 | underscoreExceptions, $exception); 25 | } 26 | 27 | /** 28 | * @param Finder $finder 29 | */ 30 | public function excludeFromFinder(Finder $finder) 31 | { 32 | $hasUnderscoreExceptions = (count($this->underscoreExceptions) > 0); 33 | $finder->exclude(array_values($this->toArray())); 34 | $finder->filter(function ($item) use ($hasUnderscoreExceptions) { 35 | /** @var SplFileInfo $item */ 36 | $relativePath = $item->getRelativePath(); 37 | if ($hasUnderscoreExceptions === true) { 38 | foreach ($this->underscoreExceptions as $exception) { 39 | if (str_contains($relativePath, $exception)) { 40 | return true; 41 | } 42 | } 43 | } 44 | 45 | foreach (explode('/', str_replace('\\', '/', $relativePath)) as $pathItem) { 46 | if (substr($pathItem, 0, 1) === '_') { 47 | return false; 48 | } 49 | } 50 | 51 | return true; 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Entities/Collections/FlatCollection.php: -------------------------------------------------------------------------------- 1 | items[$key] = $value; 13 | } 14 | 15 | public function has($key) 16 | { 17 | return isset($this->items[$key]); 18 | } 19 | 20 | public function get($key, $default = null) 21 | { 22 | if (! $this->has($key)) { 23 | return $default; 24 | } 25 | 26 | return $this->items[$key]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Entities/Configuration.php: -------------------------------------------------------------------------------- 1 | file = $file; 30 | $this->destinationPath = $destinationPath; 31 | } 32 | 33 | /** 34 | * @return File 35 | */ 36 | public function getFile() 37 | { 38 | return $this->file; 39 | } 40 | 41 | /** 42 | * @param Filesystem $filesystem 43 | * @param OutputInterface $output 44 | * 45 | * @return void 46 | */ 47 | abstract public function __invoke(Filesystem $filesystem, OutputInterface $output); 48 | } 49 | -------------------------------------------------------------------------------- /src/Entities/Filesystem/FileCopier.php: -------------------------------------------------------------------------------- 1 | file->getCompiledPermalink(); 19 | $output->writeln('[+] Copying File ['.$this->file->getUid().'] to path ['.$outputPath.']'); 20 | $filesystem->copy($this->file->getFileInfo()->getPathname(), $this->destinationPath.DIRECTORY_SEPARATOR.$outputPath); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Entities/Filesystem/FileIgnored.php: -------------------------------------------------------------------------------- 1 | writeln('[+] Ignoring File ['.$this->file->getUid().']'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Entities/Filesystem/FileWriter.php: -------------------------------------------------------------------------------- 1 | file->getCompiledPermalink(); 19 | $output->writeln('[+] Writing File ['.$this->file->getUid().'] to path ['.$outputPath.']'); 20 | $filesystem->dumpFile($this->destinationPath.DIRECTORY_SEPARATOR.$outputPath, $this->file->getContent()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Entities/Filesystem/FilesystemInterface.php: -------------------------------------------------------------------------------- 1 | file; 13 | $newFile->setData([ 14 | 'generator' => array_filter($this->file->getData('generator'), function ($value) { 15 | return $value !== 'CollectionItemGenerator'; 16 | }), 17 | ]); 18 | 19 | // Identify Previous and Next Item within this files collection 20 | 21 | if ($contentType = $this->file->getData('content_type')) { 22 | $contentType = $project->getContentType($contentType); 23 | } 24 | 25 | $siblings = array_keys($contentType->getFileList('asc')); 26 | $position = array_search($this->file->getUid(), $siblings); 27 | 28 | if (($position === (count($siblings) - 1))) { 29 | // If we are the last page, then Pagination will only have two pages (this and the previous one), also there will 30 | // be just two files in the items array 31 | 32 | $pagination = new Pagination($project, [], 2, 2); 33 | } elseif ($position === 0) { 34 | // If we are the first page, then Pagination will only have two pages (this and the next one), also there will be 35 | // just two files in the items array 36 | 37 | $pagination = new Pagination($project, [], 2, 1); 38 | } else { 39 | // Else this is the middle page of a total of three (previous, this, next) 40 | 41 | $pagination = new Pagination($project, [], 3, 2); 42 | } 43 | 44 | $pagination->setPreviousNext( 45 | (isset($siblings[$position - 1]) ? $siblings[$position - 1] : null), 46 | (isset($siblings[$position + 1]) ? $siblings[$position + 1] : null) 47 | ); 48 | 49 | // @todo check to see if 'item' should be set within the view's scope; it feels weird that this is the only generator doing so 50 | $newFile->setData(['previous_next' => $pagination, 'item' => $this->file]); 51 | 52 | return $newFile; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Entities/Generators/TaxonomyArchiveGenerator.php: -------------------------------------------------------------------------------- 1 | file->getData('use')) { 23 | return $this->file; 24 | } 25 | 26 | foreach ($uses as $use) { 27 | if (! $data = $this->file->getData($use.'_items')) { 28 | continue; 29 | } 30 | 31 | $taxonomyItems = array_keys($data); 32 | 33 | foreach ($data as $taxonomyName => $files) { 34 | $newFile = clone $this->file; 35 | $newFile->setData([ 36 | 'generator' => array_filter($this->file->getData('generator'), function ($value) { 37 | return $value !== 'TaxonomyArchiveGenerator'; 38 | }), 39 | 'taxonomyName' => $taxonomyName, 40 | $use.'_items' => $files, 41 | $use => $taxonomyItems, 42 | ]); 43 | 44 | $newFile->setUid($newFile->getUid().'_'.$taxonomyName); 45 | $newFile->setFilename($taxonomyName); 46 | array_push($generated, $newFile); 47 | unset($newFile); 48 | } 49 | } 50 | 51 | return $generated; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Entities/Generators/TaxonomyIndexGenerator.php: -------------------------------------------------------------------------------- 1 | file->hasData('use')) { 12 | $this->file->setData([ 13 | 'generator' => array_filter($this->file->getData('generator'), function ($value) { 14 | return $value !== 'TaxonomyIndexGenerator'; 15 | }), 16 | ]); 17 | 18 | return $this->file; 19 | } 20 | 21 | $newFile = clone $this->file; 22 | $newFile->setData([ 23 | 'generator' => array_filter($this->file->getData('generator'), function ($value) { 24 | return $value !== 'TaxonomyIndexGenerator'; 25 | }), 26 | ]); 27 | 28 | return $newFile; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Entities/ProjectFileGeneratorInterface.php: -------------------------------------------------------------------------------- 1 | extensions; 32 | } 33 | 34 | /** 35 | * Returns true if the renderer can render the given extension. 36 | * 37 | * @param string $extension 38 | * 39 | * @return bool 40 | */ 41 | public function canRender($extension) 42 | { 43 | return in_array($extension, $this->extensions); 44 | } 45 | 46 | /** 47 | * Render the input file content and return the output. 48 | * 49 | * @param File $file 50 | * 51 | * @return string 52 | */ 53 | public function render(File $file) 54 | { 55 | return ''; 56 | } 57 | 58 | /** 59 | * Returns the extension that the rendered output conforms to. 60 | * 61 | * @return string 62 | */ 63 | public function getDestinationExtension($ext) 64 | { 65 | return $ext; 66 | } 67 | 68 | /** 69 | * Does this renderer support frontmatter? 70 | * 71 | * @return bool 72 | */ 73 | public function supportsFrontMatter() 74 | { 75 | return false; 76 | } 77 | 78 | /** 79 | * The default action is to set a File for copying and therefore 80 | * disable its pretty permalink output. 81 | * 82 | * @param File $file 83 | * @return void 84 | */ 85 | public function mutateFile(File &$file) 86 | { 87 | $file->setToCopy(true); 88 | $file->setData([ 89 | 'pretty_permalink' => false, 90 | ]); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Entities/Renderers/MarkdownRenderer.php: -------------------------------------------------------------------------------- 1 | markdown = $markdown; 28 | } 29 | 30 | /** 31 | * Returns the renderer name. 32 | * 33 | * @return string 34 | */ 35 | public function getName() 36 | { 37 | return 'MarkdownRenderer'; 38 | } 39 | 40 | /** 41 | * Returns an array of the extensions that this renderer will support. 42 | * 43 | * @return array 44 | */ 45 | public function supportedExtensions() 46 | { 47 | return $this->extensions; 48 | } 49 | 50 | /** 51 | * Returns true if the renderer can render the given extension. 52 | * 53 | * @param string $extension 54 | * 55 | * @return bool 56 | */ 57 | public function canRender($extension) 58 | { 59 | return in_array($extension, $this->extensions); 60 | } 61 | 62 | /** 63 | * Render the input file content and return the output. 64 | * 65 | * @param File $file 66 | * 67 | * @return string 68 | */ 69 | public function render(File $file) 70 | { 71 | return $this->markdown->transform($file->getContent()); 72 | } 73 | 74 | /** 75 | * Returns the extension that the rendered output conforms to. 76 | * 77 | * @return string 78 | */ 79 | public function getDestinationExtension($ext) 80 | { 81 | return 'html'; 82 | } 83 | 84 | /** 85 | * Does this renderer support frontmatter? 86 | * 87 | * @return bool 88 | */ 89 | public function supportsFrontMatter() 90 | { 91 | return true; 92 | } 93 | 94 | /** 95 | * @param File $file 96 | * 97 | * @return void 98 | */ 99 | public function mutateFile(File &$file) 100 | { 101 | // If markdown file has a layout associated with it, we need to ensure it gets rendered within that 102 | if ($file->hasData('layout')) { 103 | $file->setExt('phtml'); // Templates are managed by the phtml renderer 104 | $file->setRendered(false); // Set rendered to false so that within Compile.php's Execute Renderers loop it gets re-rendered 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Entities/Renderers/PlatesRenderer.php: -------------------------------------------------------------------------------- 1 | parser = $parser; 35 | $this->project = $project; 36 | $this->parser->setProject($project); 37 | } 38 | 39 | /** 40 | * Returns the renderer name. 41 | * 42 | * @return string 43 | */ 44 | public function getName() 45 | { 46 | return 'PlatesRenderer'; 47 | } 48 | 49 | /** 50 | * Returns an array of the extensions that this renderer will support. 51 | * 52 | * @return array 53 | */ 54 | public function supportedExtensions() 55 | { 56 | return $this->extensions; 57 | } 58 | 59 | /** 60 | * Returns true if the renderer can render the given extension. 61 | * 62 | * @param string $extension 63 | * 64 | * @return bool 65 | */ 66 | public function canRender($extension) 67 | { 68 | return in_array($extension, $this->extensions); 69 | } 70 | 71 | /** 72 | * Render the input file content and return the output. 73 | * 74 | * @param File $file 75 | * 76 | * @return string 77 | */ 78 | public function render(File $file) 79 | { 80 | return $this->parser->renderFile($file); 81 | } 82 | 83 | /** 84 | * Returns the extension that the rendered output conforms to. 85 | * 86 | * @return string 87 | */ 88 | public function getDestinationExtension($ext) 89 | { 90 | return 'html'; 91 | } 92 | 93 | /** 94 | * Does this renderer support frontmatter? 95 | * 96 | * @return bool 97 | */ 98 | public function supportsFrontMatter() 99 | { 100 | return true; 101 | } 102 | 103 | /** 104 | * @param File $file 105 | * 106 | * @return void 107 | */ 108 | public function mutateFile(File &$file) 109 | { 110 | // ... 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Entities/Renderers/RendererInterface.php: -------------------------------------------------------------------------------- 1 | name = str_slug($name); 31 | $this->items = new Collection(); 32 | } 33 | 34 | /** 35 | * The taxonomy name. 36 | * 37 | * @return string 38 | */ 39 | public function getName() 40 | { 41 | return $this->name; 42 | } 43 | 44 | /** 45 | * @param File $file 46 | * @param $classification 47 | */ 48 | public function addFile(File $file, $classification) 49 | { 50 | $classification = str_slug($classification); 51 | if (! $this->items->has($classification)) { 52 | $this->items->set($classification, []); 53 | } 54 | 55 | $this->items->set($classification.'.'.$file->getUid(), $file->getData('date')->getTimestamp()); 56 | } 57 | 58 | /** 59 | * Returns an ordered list of the file uid's that have been bucketed into this taxonomy. The list is ordered by 60 | * the files date. 61 | * 62 | * @param string $order 63 | * @return array 64 | */ 65 | public function getFileList($order = 'desc') 66 | { 67 | $order = strtolower(trim($order)); 68 | // Order Files by date newer to older 69 | $this->items->sortMultiDimension(function ($a, $b) use ($order) { 70 | if ($a == $b) { 71 | return 0; 72 | } 73 | if ($order === 'asc') { 74 | return ($a < $b) ? -1 : 1; 75 | } 76 | 77 | return ($a > $b) ? -1 : 1; 78 | }); 79 | 80 | return $this->items->all(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Entities/ViewFile.php: -------------------------------------------------------------------------------- 1 | project = $project; 39 | $this->fileUid = $fileUid; 40 | } 41 | 42 | /** 43 | * @return File 44 | */ 45 | public function getFile() 46 | { 47 | if (is_null($this->file)) { 48 | $this->file = $this->project->get('compiled.'.$this->fileUid); 49 | } 50 | 51 | return $this->file; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Exceptions/InvalidConsoleInputException.php: -------------------------------------------------------------------------------- 1 | steps = $steps; 28 | $this->tapestry = $tapestry; 29 | } 30 | 31 | public function generate(Project $project, OutputInterface $output) 32 | { 33 | $output->writeln('Generating site from '.$project->sourceDirectory.' to '.$project->destinationDirectory.''); 34 | $stopwatch = $project->get('cmd_options.stopwatch', false); 35 | $eventEmitter = $this->tapestry->getEventEmitter(); 36 | 37 | foreach ($this->steps as $step) { 38 | $eventEmitter->emit(strtolower(class_basename($step)).'.before'); 39 | if ($stopwatch) { 40 | Tapestry::addProfile(class_basename($step).'_START'); 41 | } 42 | /** @var Step $step */ 43 | $step = $this->tapestry->getContainer()->get($step); 44 | $output->writeln('Executing step ['.class_basename($step).']'); 45 | if (! $step->__invoke($project, $output)) { 46 | return 1; 47 | } 48 | if ($stopwatch) { 49 | Tapestry::addProfile(class_basename($step).'_FINISH'); 50 | } 51 | $eventEmitter->emit(strtolower(class_basename($step)).'.after'); 52 | } 53 | 54 | return 0; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Modules/Config/DefaultConfig.php: -------------------------------------------------------------------------------- 1 | false, 8 | 9 | /* 10 | * The site kernel to be loaded during site building 11 | */ 12 | 'kernel' => \Tapestry\Modules\Kernel\DefaultKernel::class, 13 | 14 | /* 15 | * Enable / Disable pretty permalink, if enabled then /about.md will be written as /about/index.md. 16 | * This may be over-ridden on a per file basis. 17 | */ 18 | 'pretty_permalink' => true, 19 | 20 | /* 21 | * Enable / Disable the publishing of files with `draft: true` in their front matter 22 | */ 23 | 'publish_drafts' => false, 24 | 25 | /* 26 | * Tapestry Content Types 27 | */ 28 | 'content_types' => [ 29 | 'blog' => [ 30 | 'path' => '_blog', 31 | 'template' => 'blog', 32 | 'permalink' => 'blog/{year}/{slug}.html', 33 | 'enabled' => true, 34 | 'taxonomies' => [ 35 | 'tags', 36 | 'categories', 37 | ], 38 | ], 39 | ], 40 | 41 | 'content_renderers' => [ 42 | \Tapestry\Entities\Renderers\PlatesRenderer::class, 43 | \Tapestry\Entities\Renderers\HTMLRenderer::class, 44 | \Tapestry\Entities\Renderers\MarkdownRenderer::class, 45 | \Tapestry\Entities\Renderers\DefaultRenderer::class, 46 | ], 47 | 48 | 'content_generators' => [ 49 | \Tapestry\Entities\Generators\PaginationGenerator::class, 50 | \Tapestry\Entities\Generators\TaxonomyArchiveGenerator::class, 51 | \Tapestry\Entities\Generators\TaxonomyIndexGenerator::class, 52 | Tapestry\Entities\Generators\CollectionItemGenerator::class, 53 | ], 54 | 55 | /* 56 | * Paths to ignore and not parse, any path matching those listed here will not be loaded. 57 | */ 58 | 'ignore' => [ 59 | '_assets', 60 | ], 61 | 62 | /* 63 | * Paths that have been ignored, but which should be copied 1-to-1 from source to destination. This is useful for 64 | * ensuring that assets are copied, but are not parsed (which would slow things down with many files.) 65 | * 66 | * Note: Items within the copy array must exist within the ignore array otherwise 67 | * they will be ignored. 68 | */ 69 | 'copy' => [], 70 | ]; 71 | -------------------------------------------------------------------------------- /src/Modules/Content/Clean.php: -------------------------------------------------------------------------------- 1 | filesystem = $filesystem; 25 | } 26 | 27 | /** 28 | * Process the Project at current. 29 | * 30 | * @param Project $project 31 | * @param OutputInterface $output 32 | * 33 | * @return bool 34 | */ 35 | public function __invoke(Project $project, OutputInterface $output) 36 | { 37 | $tmpPath = $project->currentWorkingDirectory.DIRECTORY_SEPARATOR.'.tmp'; 38 | $output->writeln('[+] Clearing tmp folder ['.$tmpPath.']'); 39 | 40 | if (file_exists($tmpPath)) { 41 | $this->filesystem->remove($tmpPath); 42 | } 43 | 44 | return true; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Modules/Content/Clear.php: -------------------------------------------------------------------------------- 1 | filesystem = $filesystem; 26 | } 27 | 28 | /** 29 | * Process the Project at current. 30 | * 31 | * @param Project $project 32 | * @param OutputInterface $output 33 | * 34 | * @return bool 35 | */ 36 | public function __invoke(Project $project, OutputInterface $output) 37 | { 38 | if ($project->get('cmd_options.clear') === true) { 39 | $output->writeln('[+] Clearing destination folder ['.$project->destinationDirectory.']'); 40 | if (file_exists($project->destinationDirectory)) { 41 | $this->filesystem->remove($project->destinationDirectory); 42 | } 43 | 44 | $output->writeln('[+] Clearing cache'); 45 | 46 | /** @var Cache $cache */ 47 | $cache = $project->get('cache'); 48 | $cache->reset(); 49 | } 50 | 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Modules/Content/Copy.php: -------------------------------------------------------------------------------- 1 | configuration = $configuration; 32 | $this->filesystem = $filesystem; 33 | } 34 | 35 | /** 36 | * Process the Project at current. 37 | * 38 | * @param Project $project 39 | * @param OutputInterface $output 40 | * 41 | * @return bool 42 | */ 43 | public function __invoke(Project $project, OutputInterface $output) 44 | { 45 | foreach ($this->configuration->get('copy') as $path) { 46 | $finder = new Finder(); 47 | $basePath = $project->sourceDirectory.DIRECTORY_SEPARATOR.$path; 48 | 49 | if (! $this->filesystem->exists($basePath)) { 50 | $output->writeln('[!] Copy Path ['.$basePath.'] does not exist!'); 51 | continue; 52 | } 53 | 54 | /** @var SplFileInfo $file */ 55 | foreach ($finder->files()->in($basePath) as $file) { 56 | $inputPath = $project->sourceDirectory. 57 | DIRECTORY_SEPARATOR. 58 | $path. 59 | DIRECTORY_SEPARATOR. 60 | $file->getRelativePathname(); 61 | 62 | $outputPath = $project->destinationDirectory. 63 | DIRECTORY_SEPARATOR. 64 | $path. 65 | DIRECTORY_SEPARATOR. 66 | $file->getRelativePathname(); 67 | 68 | $output->writeln('[+] Copying Path ['.$inputPath.'] to path ['.$outputPath.']'); 69 | $this->filesystem->copy($inputPath, $outputPath); 70 | } 71 | } 72 | 73 | return true; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Modules/Content/FrontMatter.php: -------------------------------------------------------------------------------- 1 | body = $body; 36 | // If front matter is found, then we should parse it 37 | if (preg_match($this->pattern, $this->body, $matches)) { 38 | $this->content = trim($matches[2]); 39 | $this->parse(trim($matches[1])); 40 | } else { 41 | $this->content = $this->body; 42 | } 43 | } 44 | 45 | /** 46 | * Return an array. 47 | * 48 | * @return array 49 | */ 50 | public function getData() 51 | { 52 | return $this->data; 53 | } 54 | 55 | /** 56 | * @return string 57 | */ 58 | public function getContent() 59 | { 60 | return $this->content; 61 | } 62 | 63 | private function parse($string) 64 | { 65 | if (! preg_match('/^(\s*[-]+\s*|\s*)$/', $string)) { 66 | try { 67 | $this->data = Yaml::parse($string); 68 | } catch (ParseException $e) { 69 | // Most likely not valid YAML 70 | $this->content = $this->body; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Modules/Content/ReadCache.php: -------------------------------------------------------------------------------- 1 | finder = $finder; 27 | } 28 | 29 | /** 30 | * Invoke a new instance of the Cache system, load it and then inject it into the Project container. 31 | * 32 | * @param Project $project 33 | * @param OutputInterface $output 34 | * 35 | * @return bool 36 | */ 37 | public function __invoke(Project $project, OutputInterface $output) 38 | { 39 | $cache = new Cache($project->currentWorkingDirectory.DIRECTORY_SEPARATOR.'.'.$project->environment.'_cache', 40 | $this->createInvalidationHash($project)); 41 | $cache->load(); 42 | $project->set('cache', $cache); 43 | 44 | return true; 45 | } 46 | 47 | /** 48 | * Find files non recursively within the src folder and create a hash of their content salted with the applications 49 | * version number. This ensures that the cache is invalidated upon either the base directory changing (including 50 | * config.php and kernel.php, or files such as Gulp, Grunt config;) as well as if the user updates their version of 51 | * the application. 52 | * 53 | * @param Project $project 54 | * @return string 55 | */ 56 | private function createInvalidationHash(Project $project) 57 | { 58 | $files = $this->finder->files()->in($project->currentWorkingDirectory)->depth('== 0'); 59 | $hash = []; 60 | 61 | /** @var SplFileInfo $file */ 62 | foreach ($files as $file) { 63 | array_push($hash, sha1_file($file->getPathname())); 64 | } 65 | 66 | array_push($hash, sha1(Tapestry::VERSION)); 67 | 68 | return sha1(implode('.', $hash)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Modules/Content/WriteCache.php: -------------------------------------------------------------------------------- 1 | get('cache'); 27 | 28 | /** @var FlatCollection $invalidation */ 29 | $invalidation = $project->get('file_layout_cache'); 30 | 31 | /** @var FilesystemInterface $file */ 32 | foreach ($project['compiled']->all() as $file) { 33 | $f = $file->getFile(); 34 | $cache->setItem($f->getUid(), new CachedFile($f, $invalidation->get($f->getUid(), []), $project->sourceDirectory)); 35 | } 36 | 37 | $cache->save(); 38 | 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Modules/Content/WriteFiles.php: -------------------------------------------------------------------------------- 1 | filesystem = $filesystem; 33 | $this->configuration = $configuration; 34 | } 35 | 36 | /** 37 | * Process the Project at current. 38 | * 39 | * @param Project $project 40 | * @param OutputInterface $output 41 | * 42 | * @return bool 43 | */ 44 | public function __invoke(Project $project, OutputInterface $output) 45 | { 46 | if ($project->get('cmd_options.no-write') === true) { 47 | return true; 48 | } 49 | 50 | /** @var FilesystemInterface $file */ 51 | foreach ($project['compiled']->all() as $file) { 52 | $file->__invoke($this->filesystem, $output); 53 | } 54 | 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Modules/ContentTypes/LoadContentTypes.php: -------------------------------------------------------------------------------- 1 | configuration = $configuration; 26 | } 27 | 28 | /** 29 | * Process the Project at current. 30 | * 31 | * @param Project $project 32 | * @param OutputInterface $output 33 | * 34 | * @return bool 35 | */ 36 | public function __invoke(Project $project, OutputInterface $output) 37 | { 38 | if (! $contentTypes = $this->configuration->get('content_types', null)) { 39 | $output->writeln('[!] Your project\'s content types are miss-configured. Doing nothing and exiting.]'); 40 | } 41 | 42 | $contentTypeFactory = new ContentTypeFactory([ 43 | new ContentType('default', [ 44 | 'path' => '*', 45 | 'permalink' => '*', 46 | 'enabled' => true, 47 | ]), 48 | ]); 49 | 50 | foreach ($contentTypes as $name => $settings) { 51 | $contentTypeFactory->add(new ContentType($name, $settings)); 52 | } 53 | 54 | $project->set('content_types', $contentTypeFactory); 55 | 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Modules/Generators/ContentGeneratorFactory.php: -------------------------------------------------------------------------------- 1 | add($item); 18 | } 19 | } 20 | 21 | public function add($class) 22 | { 23 | $reflection = new \ReflectionClass($class); 24 | $this->items[$reflection->getShortName()] = $class; 25 | } 26 | 27 | public function get($name, File $file) 28 | { 29 | return new $this->items[$name]($file); 30 | } 31 | 32 | public function has($name) 33 | { 34 | return isset($this->items[$name]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Modules/Generators/LoadContentGenerators.php: -------------------------------------------------------------------------------- 1 | configuration = $configuration; 26 | $this->container = $tapestry->getContainer(); 27 | } 28 | 29 | /** 30 | * Process the Project at current. 31 | * 32 | * @param Project $project 33 | * @param OutputInterface $output 34 | * 35 | * @return bool 36 | */ 37 | public function __invoke(Project $project, OutputInterface $output) 38 | { 39 | if (! $contentGenerators = $this->configuration->get('content_generators', null)) { 40 | $output->writeln('[!] Your project\'s content generators are miss-configured. Doing nothing and exiting.]'); 41 | exit(1); 42 | } 43 | 44 | $project->set('content_generators', new ContentGeneratorFactory($contentGenerators)); 45 | 46 | return true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Modules/Kernel/BootKernel.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 26 | $this->configuration = $configuration; 27 | } 28 | 29 | /** 30 | * Process the Project at current. 31 | * 32 | * @param Project $project 33 | * @param OutputInterface $output 34 | * 35 | * @return bool 36 | */ 37 | public function __invoke(Project $project, OutputInterface $output) 38 | { 39 | /** @var KernelInterface $kernel */ 40 | $kernel = $this->tapestry->getContainer()->get(KernelInterface::class); 41 | $kernel->boot(); 42 | 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Modules/Kernel/DefaultKernel.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 22 | } 23 | 24 | public function register() 25 | { 26 | // ... 27 | } 28 | 29 | public function boot() 30 | { 31 | // ... 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Modules/Kernel/KernelInterface.php: -------------------------------------------------------------------------------- 1 | container = $tapestry->getContainer(); 32 | $this->configuration = $configuration; 33 | } 34 | 35 | /** 36 | * @param Project $project 37 | * @param OutputInterface $output 38 | * 39 | * @return bool 40 | */ 41 | public function __invoke(Project $project, OutputInterface $output) 42 | { 43 | if (! $contentRenderers = $this->configuration->get('content_renderers', null)) { 44 | $output->writeln('[!] Your project\'s content renderers are miss-configured. Doing nothing and exiting.]'); 45 | } 46 | 47 | $contentRendererFactory = new ContentRendererFactory(); 48 | 49 | foreach ($contentRenderers as $renderer) { 50 | $contentRendererFactory->add($this->container->get($renderer)); 51 | } 52 | 53 | $project->set('content_renderers', $contentRendererFactory); 54 | 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Modules/Scripts/After.php: -------------------------------------------------------------------------------- 1 | tapestry->getEventEmitter()->emit('scripts.after'); 22 | 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Modules/Scripts/Before.php: -------------------------------------------------------------------------------- 1 | tapestry->getEventEmitter()->emit('scripts.before'); 22 | 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Modules/Scripts/Script.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Plates/Engine.php: -------------------------------------------------------------------------------- 1 | project = $project; 20 | $this->project->set('file_layout_cache', new FlatCollection()); 21 | } 22 | 23 | public function getProject() 24 | { 25 | return $this->project; 26 | } 27 | 28 | /** 29 | * Create a new template. 30 | * 31 | * @param string $name 32 | * 33 | * @return Template 34 | */ 35 | public function make($name) 36 | { 37 | return new Template($this, $name); 38 | } 39 | 40 | /** 41 | * Create a new template and render it. 42 | * 43 | * @param File $file 44 | * 45 | * @return string 46 | */ 47 | public function renderFile(File $file) 48 | { 49 | return $this->make( 50 | $file->getFileInfo()->getRelativePath(). 51 | DIRECTORY_SEPARATOR. 52 | pathinfo($file->getFileInfo()->getFilename(), PATHINFO_FILENAME) 53 | )->renderFile($file); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Plates/Extensions/Environment.php: -------------------------------------------------------------------------------- 1 | environment = $project->environment; 23 | } 24 | 25 | public function register(Engine $engine) 26 | { 27 | $engine->registerFunction('getEnvironment', [$this, 'getEnvironment']); 28 | } 29 | 30 | public function getEnvironment() 31 | { 32 | return $this->environment; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Plates/Extensions/Helpers.php: -------------------------------------------------------------------------------- 1 | registerFunction('getFile', [$this, 'getFile']); 26 | $class = new \ReflectionClass(ViewFileTrait::class); 27 | foreach ($class->getMethods() as $method) { 28 | if ($method->name === 'getFile') { 29 | continue; 30 | } 31 | $engine->registerFunction($method->name, [$this, $method->name]); 32 | } 33 | } 34 | 35 | /** 36 | * @return File 37 | */ 38 | public function getFile() 39 | { 40 | return $this->template->getFile(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Plates/Extensions/Site.php: -------------------------------------------------------------------------------- 1 | configuration = $configuration; 24 | } 25 | 26 | public function register(Engine $engine) 27 | { 28 | $engine->registerFunction('site', [$this, 'site']); 29 | } 30 | 31 | public function site($key, $default = null) 32 | { 33 | $key = 'site.'.$key; 34 | if ($value = $this->configuration->get($key, $default)) { 35 | return $value; 36 | } 37 | 38 | return $default; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Plates/Extensions/Url.php: -------------------------------------------------------------------------------- 1 | url = $url; 23 | } 24 | 25 | public function register(Engine $engine) 26 | { 27 | $engine->registerFunction('url', [$this, 'url']); 28 | } 29 | 30 | public function url($uri = '') 31 | { 32 | return $this->url->parse($uri); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Profiler.php: -------------------------------------------------------------------------------- 1 | items, [ 24 | 'name' => $name, 25 | 'time' => is_null($time) ? microtime(true) : $time, 26 | 'memory_use' => is_null($memoryUse) ? memory_get_usage(true) : $memoryUse, 27 | 'memory_peak' => is_null($memoryPeak) ? memory_get_peak_usage(true) : $memoryPeak, 28 | ]); 29 | } 30 | 31 | public function report() 32 | { 33 | $report = []; 34 | foreach ($this->items as $item) { 35 | $name = explode('_', $item['name']); 36 | $status = $name[1]; 37 | $name = $name[0]; 38 | 39 | if (! isset($report[$name])) { 40 | $report[$name] = []; 41 | } 42 | 43 | $report[$name][$status.'_time'] = $item['time']; 44 | $report[$name][$status.'_memory_use'] = $item['memory_use']; 45 | $report[$name][$status.'_memory_peak'] = $item['memory_peak']; 46 | 47 | // If a start & finish time are available, then work out the stats 48 | if (isset($report[$name]['START_time']) && isset($report[$name]['FINISH_time'])) { 49 | $report[$name]['execution_time'] = round(($report[$name]['FINISH_time'] - $report[$name]['START_time']), 3); 50 | $report[$name]['memory_consumption'] = $report[$name]['FINISH_memory_use'] - $report[$name]['START_memory_use']; 51 | $report[$name]['memory_use'] = $report[$name]['FINISH_memory_use']; 52 | $report[$name]['memory_peak'] = ($report[$name]['START_memory_peak'] < $report[$name]['FINISH_memory_peak']) ? $report[$name]['FINISH_memory_peak'] : $report[$name]['START_memory_peak']; 53 | } 54 | } 55 | 56 | // Filter out any clocks that have no start or finish time, this should probably throw an exception in debug mode? 57 | $report = array_filter($report, function ($value) { 58 | return isset($value['START_time']) && isset($value['FINISH_time']); 59 | }); 60 | 61 | return $report; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Providers/CompileStepsServiceProvider.php: -------------------------------------------------------------------------------- 1 | container property or the `getContainer` method 35 | * from the ContainerAwareTrait. 36 | * 37 | * @return void 38 | */ 39 | public function register() 40 | { 41 | $steps = [ 42 | BootKernel::class, 43 | ReadCache::class, 44 | Before::class, 45 | Clear::class, 46 | LoadContentTypes::class, 47 | LoadContentRenderers::class, 48 | LoadContentGenerators::class, 49 | LoadSourceFiles::class, 50 | Json::class, 51 | ParseContentTypes::class, 52 | Compile::class, 53 | WriteFiles::class, 54 | WriteCache::class, 55 | Copy::class, 56 | Clean::class, 57 | After::class, 58 | ]; 59 | 60 | $this->getContainer()->add('Compile.Steps', $steps); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Providers/PlatesServiceProvider.php: -------------------------------------------------------------------------------- 1 | container property or the `getContainer` method 25 | * from the ContainerAwareTrait. 26 | * 27 | * @return void 28 | */ 29 | public function register() 30 | { 31 | $container = $this->getContainer(); 32 | 33 | /** @var Project $project */ 34 | $project = $container->get(Project::class); 35 | 36 | $container->share(Engine::class, function () use ($project, $container) { 37 | $engine = new Engine($project->sourceDirectory, 'phtml'); 38 | $engine->loadExtension($container->get(Site::class)); 39 | $engine->loadExtension($container->get(Url::class)); 40 | $engine->loadExtension($container->get(Helpers::class)); 41 | $engine->loadExtension($container->get(Environment::class)); 42 | 43 | return $engine; 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Providers/ProjectConfigurationServiceProvider.php: -------------------------------------------------------------------------------- 1 | container property or the `getContainer` method 22 | * from the ContainerAwareTrait. 23 | * 24 | * @return void 25 | */ 26 | public function register() 27 | { 28 | $container = $this->getContainer(); 29 | 30 | /** @var Tapestry $tapestry */ 31 | $tapestry = $container->get(Tapestry::class); 32 | $configuration = new Configuration(include(__DIR__.'/../../src/Modules/Config/DefaultConfig.php')); 33 | 34 | if ($baseConfigPathName = $this->identifyConfigurationPath($tapestry['currentWorkingDirectory'])) { 35 | $configuration->merge($this->getConfigurationFromPath($baseConfigPathName)); 36 | } 37 | 38 | if ($envConfigPathName = $this->identifyConfigurationPath($tapestry['currentWorkingDirectory'], $tapestry['environment'])) { 39 | $configuration->merge($this->getConfigurationFromPath($envConfigPathName)); 40 | } 41 | 42 | $container->share(Configuration::class, $configuration); 43 | } 44 | 45 | private function identifyConfigurationPath($configPath, $env = null) 46 | { 47 | $basePath = $configPath.DIRECTORY_SEPARATOR.'config'.(is_null($env) ? '' : ('-'.$env)); 48 | $PHPPath = $basePath.'.php'; 49 | $YAMLPath = $basePath.'.yaml'; 50 | $configPHPExists = file_exists($PHPPath); 51 | $configYAMLExists = file_exists($YAMLPath); 52 | if ($configPHPExists && $configYAMLExists) { 53 | throw new \Exception('Configuration can only be either PHP or YAML based, not both.'); 54 | } 55 | if ($configPHPExists) { 56 | return $PHPPath; 57 | } 58 | if ($configYAMLExists) { 59 | return $YAMLPath; 60 | } 61 | 62 | return null; 63 | } 64 | 65 | private function getConfigurationFromPath($path) 66 | { 67 | if (strpos($path, 'php') !== false) { 68 | return include $path; 69 | } 70 | if (strpos($path, 'yaml') !== false) { 71 | return Yaml::parse(file_get_contents($path)); 72 | } 73 | 74 | return []; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Providers/ProjectKernelServiceProvider.php: -------------------------------------------------------------------------------- 1 | container property or the `getContainer` method 25 | * from the ContainerAwareTrait. 26 | * 27 | * @return void 28 | */ 29 | public function register() 30 | { 31 | } 32 | 33 | /** 34 | * Method will be invoked on registration of a service provider implementing 35 | * this interface. Provides ability for eager loading of Service Providers. 36 | * @return void 37 | * @throws Exception 38 | */ 39 | public function boot() 40 | { 41 | $container = $this->getContainer(); 42 | 43 | /** @var Tapestry $tapestry */ 44 | $tapestry = $container->get(Tapestry::class); 45 | $configuration = $container->get(Configuration::class); 46 | $kernelPath = $tapestry['currentWorkingDirectory'].DIRECTORY_SEPARATOR.'kernel.php'; 47 | 48 | if (! file_exists($kernelPath)) { 49 | $kernelPath = $tapestry['currentWorkingDirectory'].DIRECTORY_SEPARATOR.'Kernel.php'; 50 | } 51 | 52 | if (file_exists($kernelPath)) { 53 | $kernelClassName = $configuration->get('kernel', DefaultKernel::class); 54 | 55 | if (! class_exists($kernelClassName)) { 56 | include $kernelPath; 57 | } 58 | 59 | if (! class_exists($kernelClassName)) { 60 | throw new Exception('['.$kernelClassName.'] kernel file not found.'); 61 | } 62 | 63 | $container->share(KernelInterface::class, $kernelClassName)->withArgument( 64 | $container->get(Tapestry::class) 65 | ); 66 | } else { 67 | $container->share(KernelInterface::class, DefaultKernel::class)->withArgument( 68 | $container->get(Tapestry::class) 69 | ); 70 | } 71 | 72 | /** @var KernelInterface $kernel */ 73 | $kernel = $container->get(KernelInterface::class); 74 | $kernel->register(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Providers/ProjectServiceProvider.php: -------------------------------------------------------------------------------- 1 | container property or the `getContainer` method 20 | * from the ContainerAwareTrait. 21 | * 22 | * @return void 23 | */ 24 | public function register() 25 | { 26 | $container = $this->getContainer(); 27 | $container->share(Project::class, function () use ($container) { 28 | $project = new Project($container->get('currentWorkingDirectory'), $container->get('destinationDirectory'), $container->get('environment')); 29 | $project->set('cmd_options', $container->get('cmd_options')); 30 | 31 | return $project; 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Scaffold/.gitignore: -------------------------------------------------------------------------------- 1 | /.tmp/ 2 | /build_local/ 3 | /node_modules/ 4 | /vendor/ 5 | /source/img 6 | /source/css 7 | /source/js 8 | -------------------------------------------------------------------------------- /src/Scaffold/config.php: -------------------------------------------------------------------------------- 1 | site(...) in any phtml file 6 | */ 7 | 'site' => [ 8 | 'title' => 'Tapestry Scaffold', 9 | 'url' => 'http://localhost:3000', 10 | 'description' => 'Basic site scaffold for the Tapestry static site generator.', 11 | 'author' => 'Some One', 12 | 'email' => 'some.one@example.com', 13 | ], 14 | 15 | /* 16 | * The site kernel to be loaded during site building 17 | */ 18 | 'kernel' => \Site\SiteKernel::class, 19 | ]; 20 | -------------------------------------------------------------------------------- /src/Scaffold/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var elixir = require('laravel-elixir'); 3 | var argv = require('yargs').argv; 4 | 5 | require('laravel-elixir-imagemin'); 6 | 7 | elixir.config.assetsPath = 'source/_assets'; 8 | elixir.config.publicPath = 'source'; 9 | elixir.config.images = { 10 | folder: 'img', 11 | outputFolder: 'img' 12 | }; 13 | 14 | elixir(function (mix) { 15 | var env = argv.e || argv.env || 'local'; 16 | var port = argv.p || argv.port || 3000; 17 | 18 | mix.less('main.less') 19 | .imagemin() 20 | .copy(elixir.config.assetsPath + '/img/favicon.ico', elixir.config.publicPath + '/img/favicon.ico') 21 | .scripts([ 22 | 'app.js' 23 | ]) 24 | .exec('php ../bin/tapestry.php build --quiet --env=' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*']) 25 | .browserSync({ 26 | port: port, 27 | server: {baseDir: 'build_' + env}, 28 | proxy: null, 29 | files: ['build_' + env + '/**/*'] 30 | }); 31 | }); -------------------------------------------------------------------------------- /src/Scaffold/kernel.php: -------------------------------------------------------------------------------- 1 | tapestry = $tapestry; 23 | } 24 | 25 | /** 26 | * This method is executed by Tapestry when the Kernel is registered. 27 | * 28 | * @return void 29 | */ 30 | public function register() 31 | { 32 | // ... 33 | } 34 | 35 | /** 36 | * This method of executed by Tapestry as part of the build process. 37 | * 38 | * @return void 39 | */ 40 | public function boot() 41 | { 42 | // ... 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Scaffold/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "basscss": "^8.0.3" 5 | }, 6 | "devDependencies": { 7 | "gulp": "^3.8.8", 8 | "laravel-elixir": "^4.2.0", 9 | "laravel-elixir-imagemin": "^0.2.3", 10 | "yargs": "^4.6.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Scaffold/source/_assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapestry-cloud/tapestry/f3fc980b2484ccbe609a7f811c65b91254e8720e/src/Scaffold/source/_assets/img/favicon.ico -------------------------------------------------------------------------------- /src/Scaffold/source/_assets/js/app.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapestry-cloud/tapestry/f3fc980b2484ccbe609a7f811c65b91254e8720e/src/Scaffold/source/_assets/js/app.js -------------------------------------------------------------------------------- /src/Scaffold/source/_assets/less/main.less: -------------------------------------------------------------------------------- 1 | @import (inline) "../../../node_modules/basscss/css/basscss.css"; 2 | 3 | body, html { 4 | border:0; 5 | margin:0; 6 | font-family: Roboto, sans-serif; 7 | background-color: #f9f9f9; 8 | } 9 | 10 | .bg-black{ 11 | background-color: #2e3436; 12 | } 13 | 14 | .white{ 15 | color: #f9f9f9; 16 | } 17 | 18 | header a { 19 | color: #f9f9f9; 20 | } 21 | -------------------------------------------------------------------------------- /src/Scaffold/source/_blog/2016-01-01-hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | draft: false 4 | categories: 5 | - misc 6 | --- 7 | 8 | This is your first blog post. Visit [tapestry.cloud](http://tapestry.cloud) for documentation on how to use Tapestry. -------------------------------------------------------------------------------- /src/Scaffold/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= (isset($title) ? ($title . ' — ' . $this->site('title')) : $this->site('title')); ?> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |

site('title') ?>

20 | 23 |
24 |
25 |
26 | 27 |
28 | section('content') ?> 29 |
30 | 31 | -------------------------------------------------------------------------------- /src/Scaffold/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | generator: 3 | - CollectionItemGenerator 4 | --- 5 | layout('_templates\default', ['title' => $title]); 14 | ?> 15 | 16 |
17 |
18 |

19 |
20 | getDate()->format('l jS \of F Y') ?> 21 |
22 |
23 |
getContent() ?>
24 |
-------------------------------------------------------------------------------- /src/Scaffold/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: My Website 4 | use: 5 | - blog 6 | --- 7 | 8 |
9 |

Posts

10 | 23 |
24 | -------------------------------------------------------------------------------- /src/Step.php: -------------------------------------------------------------------------------- 1 | hash.'] '.$build->date; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/bootstrap.php: -------------------------------------------------------------------------------- 1 | = 5.4 in order to use Tapestry. Please upgrade your PHP version.'); 9 | } 10 | if (! ini_get('date.timezone')) { 11 | date_default_timezone_set('UTC'); 12 | } 13 | 14 | setlocale(LC_ALL, 'en_US.UTF8'); 15 | 16 | // Phar includes 17 | if (isset($include)) { 18 | require_once $include.'/vendor/autoload.php'; 19 | } elseif (file_exists(__DIR__.'/../vendor/autoload.php')) { 20 | require_once __DIR__.'/../vendor/autoload.php'; 21 | } elseif (file_exists(__DIR__.'/../../../autoload.php')) { 22 | require_once __DIR__.'/../../../autoload.php'; 23 | } else { 24 | echo 'Please run composer install.'.PHP_EOL; 25 | exit(1); 26 | } 27 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tapestry-cloud/tapestry/f3fc980b2484ccbe609a7f811c65b91254e8720e/tests/.gitkeep -------------------------------------------------------------------------------- /tests/CommandLineApplicationTest.php: -------------------------------------------------------------------------------- 1 | runCommand('', '--version'); 12 | $this->assertEquals('Tapestry version '.Tapestry::VERSION.', environment local', trim($output->getDisplay())); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/CopyTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_32/src', '_tmp'); 24 | $output = $this->runCommand('build', '--quiet'); 25 | $this->assertEquals('', trim($output->getDisplay())); 26 | $this->assertEquals(0, $output->getStatusCode()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/FileTest.php: -------------------------------------------------------------------------------- 1 | assertNotEmpty($file->getUid()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/FrontmatterTest.php: -------------------------------------------------------------------------------- 1 | getFileContent()); 19 | $this->assertSame('', $frontMatter->getContent()); 20 | $this->assertSame([ 21 | 'title' => 'Test File Title', 22 | 'draft' => false, 23 | 'date' => 507600000 24 | ], $frontMatter->getData()); 25 | } 26 | 27 | function testFrontMatterAndBodyParsedCorrectly() 28 | { 29 | $file = new File(new SplFileInfo(__DIR__ . '/Mocks/TestFile.md', '', '')); 30 | $frontMatter = new FrontMatter($file->getFileContent()); 31 | $this->assertSame('This is a test file...', $frontMatter->getContent()); 32 | $this->assertSame([ 33 | 'title' => 'Test File Title', 34 | 'draft' => false, 35 | 'date' => 507600000 36 | ], $frontMatter->getData()); 37 | } 38 | 39 | function testFrontMatterParsedWhenEmpty() 40 | { 41 | $frontMatter = new FrontMatter("---\n---\nHello World"); 42 | $this->assertSame('Hello World', $frontMatter->getContent()); 43 | $this->assertSame([], $frontMatter->getData()); 44 | 45 | $frontMatter = new FrontMatter("---\n---\n\n\nHello World"); 46 | $this->assertSame('Hello World', $frontMatter->getContent()); 47 | $this->assertSame([], $frontMatter->getData()); 48 | 49 | $frontMatter = new FrontMatter("---\r\n---\r\nHello World"); 50 | $this->assertSame('Hello World', $frontMatter->getContent()); 51 | $this->assertSame([], $frontMatter->getData()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/HelpersTest.php: -------------------------------------------------------------------------------- 1 | mockTapestry(); 20 | $tapestry->getContainer()->add(Configuration::class, new Configuration([ 21 | 'test' => 'hello world', 22 | '1234' => 'abcd' 23 | ])); 24 | 25 | $this->assertSame('hello world', config('test')); 26 | $this->assertSame('abcd', config('1234')); 27 | $this->assertNull(config('missing')); 28 | $this->assertSame('hello world', config('missing', 'hello world')); 29 | $this->assertSame(1234, config('missing', 1234)); 30 | $this->assertSame(true, config('missing', true)); 31 | $this->assertSame(false, config('missing', false)); 32 | $this->assertSame(-1, config('missing', -1)); 33 | 34 | $this->assertInstanceOf(Configuration::class, config()); 35 | } 36 | 37 | /** 38 | * Written for issue #184 39 | * @version 1.0.8 40 | * @link https://github.com/tapestry-cloud/tapestry/issues/184 41 | */ 42 | public function testFileSizeConvertHelper() 43 | { 44 | $this->assertSame('0 b', file_size_convert(0)); 45 | $this->assertSame('0 b', file_size_convert(null)); 46 | $this->assertSame('0 b', file_size_convert(-1)); 47 | $this->assertSame('0 b', file_size_convert('abc')); 48 | $this->assertSame('0 b', file_size_convert('FFF')); 49 | 50 | $this->assertSame('1000 b', file_size_convert('1000')); 51 | $this->assertSame('1000 b', file_size_convert(1000)); 52 | 53 | $this->assertSame('1 kb', file_size_convert(1024)); 54 | $this->assertSame('1 mb', file_size_convert(1048576)); 55 | $this->assertSame('1 gb', file_size_convert(1073741824)); 56 | $this->assertSame('1 tb', file_size_convert(1099511627776)); 57 | $this->assertSame('1 pb', file_size_convert(1125899906842624)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/JsonApiTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_1/src', '_tmp'); 10 | $output = $this->runCommand('build', '--quiet --json'); 11 | $this->assertEquals(0, $output->getStatusCode()); 12 | $this->assertFileExists(__DIR__ . '/_tmp/db.json'); 13 | } 14 | 15 | public function testNoWriteBuildFlag() 16 | { 17 | $this->copyDirectory('assets/build_test_1/src', '_tmp'); 18 | $output = $this->runCommand('build', '--quiet --json --no-write'); 19 | $this->assertEquals(0, $output->getStatusCode()); 20 | $this->assertFileExists(__DIR__ . '/_tmp/db.json'); 21 | $this->assertFileNotExists(__DIR__ . '/_tmp/build_local'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/LockFileTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_40/src', '_tmp'); 14 | $lock = fopen(__DIR__ . DIRECTORY_SEPARATOR . '_tmp' . DIRECTORY_SEPARATOR . '.lock', 'w+'); 15 | $this->assertTrue(flock($lock, LOCK_EX | LOCK_NB)); 16 | 17 | $output = $this->runCommand('build', ''); 18 | $this->assertEquals(1, $output->getStatusCode()); 19 | } 20 | 21 | /** 22 | * Written for issue #157 23 | * @link https://github.com/carbontwelve/tapestry/issues/157 24 | */ 25 | public function testIgnoringLockFile() 26 | { 27 | $this->copyDirectory('assets/build_test_40/src', '_tmp'); 28 | $output = $this->runCommand('build', '--no-lock'); 29 | $this->assertEquals(0, $output->getStatusCode()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/MarkdownLayoutTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_19/src', '_tmp'); 10 | $output = $this->runCommand('build', '--quiet'); 11 | $this->assertEquals(0, $output->getStatusCode()); 12 | 13 | $this->assertFileEquals( 14 | __DIR__.'/assets/build_test_19/check/test.html', 15 | __DIR__.'/_tmp/build_local/test/index.html', 16 | '', 17 | true 18 | ); 19 | } 20 | 21 | public function testMarkdownFilesGetRenderedInChildLayouts() 22 | { 23 | $this->copyDirectory('assets/build_test_20/src', '_tmp'); 24 | $output = $this->runCommand('build', '--quiet'); 25 | $this->assertEquals(0, $output->getStatusCode()); 26 | 27 | $this->assertFileEquals( 28 | __DIR__.'/assets/build_test_20/check/test.html', 29 | __DIR__.'/_tmp/build_local/test/index.html', 30 | '', 31 | true 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/MockArrayAccessByKeyClass.php: -------------------------------------------------------------------------------- 1 | items = $items; 12 | } 13 | 14 | public function arrayAccessByKey($key) 15 | { 16 | if (!isset($this->items[$key])) { 17 | return; 18 | } 19 | 20 | return $this->items[$key]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-01-a.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test A 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-02-b.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test B 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-03-c.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test C 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-04-d.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test D 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-05-e.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test E 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TaxonomyMocks/2016-01-05-f.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test F 3 | draft: false 4 | --- 5 | 6 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TestCategoryPermalinkTag.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test md post" 3 | categories: 4 | - category1 5 | - category2 6 | - category3 7 | permalink: /{category}/{slug}/index.html 8 | --- 9 | Hello world! -------------------------------------------------------------------------------- /tests/Mocks/TestEnvironmentFile.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test 3 | --- 4 | env: getEnvironment() ?> -------------------------------------------------------------------------------- /tests/Mocks/TestFile.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test File Title 3 | draft: false 4 | date: 1986-02-01 5 | --- 6 | 7 | This is a test file... -------------------------------------------------------------------------------- /tests/Mocks/TestFileNoBody.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test File Title 3 | draft: false 4 | date: 1986-02-01 5 | --- -------------------------------------------------------------------------------- /tests/Mocks/TestPaginatorFile.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test 3 | generator: 4 | - PaginationGenerator 5 | pagination: 6 | provider: test 7 | perPage: 6 8 | --- 9 | Test Pagination -------------------------------------------------------------------------------- /tests/Mocks/TestPaginatorSkipFile.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test 3 | generator: 4 | - PaginationGenerator 5 | pagination: 6 | provider: test 7 | perPage: 6 8 | skip: 6 9 | --- 10 | Test Pagination -------------------------------------------------------------------------------- /tests/PaginationGeneratorTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_17/src', '_tmp'); 10 | $output = $this->runCommand('build', '--quiet'); 11 | $this->assertEquals(0, $output->getStatusCode()); 12 | 13 | $this->assertFileExists(__DIR__.'/_tmp/build_local/blog/index.html'); 14 | $this->assertFileExists(__DIR__.'/_tmp/build_local/blog/2/index.html'); 15 | } 16 | 17 | public function testPaginationNextPrevious() 18 | { 19 | $this->copyDirectory('assets/build_test_17/src', '_tmp'); 20 | $output = $this->runCommand('build', '--quiet'); 21 | $this->assertEquals(0, $output->getStatusCode()); 22 | 23 | $this->assertFileEquals( 24 | __DIR__.'/assets/build_test_17/check/1.html', 25 | __DIR__.'/_tmp/build_local/blog/index.html', 26 | '', 27 | true 28 | ); 29 | 30 | $this->assertFileEquals( 31 | __DIR__.'/assets/build_test_17/check/2.html', 32 | __DIR__.'/_tmp/build_local/blog/2/index.html', 33 | '', 34 | true 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/PlatesExtensionsTest.php: -------------------------------------------------------------------------------- 1 | mockViewFile( 21 | $this->mockTapestry(__DIR__ . DIRECTORY_SEPARATOR . '_tmp'), 22 | __DIR__ . '/Mocks/TestEnvironmentFile.phtml', true 23 | ); 24 | $this->assertEquals('env: testing', $viewFile->getContent()); 25 | 26 | // Test with custom env set 27 | $viewFile = $this->mockViewFile( 28 | $this->mockTapestry( 29 | __DIR__ . DIRECTORY_SEPARATOR . '_tmp', 30 | null, 31 | 'abc123' 32 | ), 33 | __DIR__ . '/Mocks/TestEnvironmentFile.phtml', true 34 | ); 35 | $this->assertEquals('env: abc123', $viewFile->getContent()); 36 | } 37 | } -------------------------------------------------------------------------------- /tests/RendererTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('/assets/build_test_34/src', '/_tmp'); 16 | 17 | $project = new Project(__DIR__ . '/_tmp', __DIR__ . '/_tmp/build_test', 'test'); 18 | $renderer = new HTMLRenderer($project); 19 | 20 | $this->assertEquals(['htm', 'html'], $renderer->supportedExtensions()); 21 | $this->assertTrue($renderer->canRender('html')); 22 | $this->assertTrue($renderer->canRender('htm')); 23 | $this->assertFalse($renderer->canRender('php')); 24 | $this->assertEquals('html', $renderer->getDestinationExtension('ext')); 25 | $this->assertTrue($renderer->supportsFrontMatter()); 26 | 27 | $file = $this->mockFile(__DIR__ . '/_tmp/source/test.html'); 28 | $this->assertEquals('Hello World', trim($renderer->render($file))); 29 | 30 | $renderer->mutateFile($file); 31 | $this->assertFalse($file->isRendered()); 32 | $this->assertEquals('Hello World', $file->getData('content')); 33 | $this->assertEquals('phtml', $file->getExt()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/StopwatchProfilerTest.php: -------------------------------------------------------------------------------- 1 | addItem('BootKernel_START', 100000, 100, 100); 14 | $profiler->addItem('BootKernel_FINISH', 100100, 200, 250); 15 | 16 | $profiler->addItem('ReadCache_START', 100110, 200, 250); 17 | $profiler->addItem('ReadCache_FINISH', 100250, 220, 250); 18 | 19 | $profiler->addItem('Compile_START', 100250, 220, 250); 20 | 21 | $profiler->addItem('Compile.SubTaskA_START', 100270, 220, 250); 22 | $profiler->addItem('Compile.SubTaskA_FINISH', 100570, 350, 450); 23 | 24 | $profiler->addItem('Compile.SubTaskB_START', 100570, 350, 450); 25 | $profiler->addItem('Compile.SubTaskB_FINISH', 100970, 650, 650); 26 | 27 | $profiler->addItem('Compile_FINISH', 101250, 720, 850); 28 | 29 | $report = $profiler->report(); 30 | 31 | $this->assertTrue(key_exists('BootKernel', $report)); 32 | $this->assertEquals(100, $report['BootKernel']['execution_time']); 33 | $this->assertEquals(100, $report['BootKernel']['memory_consumption']); 34 | 35 | $this->assertTrue(key_exists('ReadCache', $report)); 36 | $this->assertEquals(140, $report['ReadCache']['execution_time']); 37 | $this->assertEquals(20, $report['ReadCache']['memory_consumption']); 38 | 39 | $this->assertTrue(key_exists('Compile', $report)); 40 | $this->assertEquals(1000, $report['Compile']['execution_time']); 41 | $this->assertEquals(500, $report['Compile']['memory_consumption']); 42 | 43 | $this->assertTrue(key_exists('Compile.SubTaskA', $report)); 44 | $this->assertEquals(300, $report['Compile.SubTaskA']['execution_time']); 45 | $this->assertEquals(130, $report['Compile.SubTaskA']['memory_consumption']); 46 | 47 | $this->assertTrue(key_exists('Compile.SubTaskB', $report)); 48 | $this->assertEquals(400, $report['Compile.SubTaskB']['execution_time']); 49 | $this->assertEquals(300, $report['Compile.SubTaskB']['memory_consumption']); 50 | } 51 | } -------------------------------------------------------------------------------- /tests/TaxonomyArchiveGeneratorTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_23/src', '_tmp'); 20 | 21 | // 22 | $definitions = new DefaultInputDefinition(); 23 | 24 | $tapestry = new Tapestry(new ArrayInput([ 25 | '--site-dir' => __DIR__ . DIRECTORY_SEPARATOR . '_tmp', 26 | '--env' => 'testing' 27 | ], $definitions)); 28 | $generator = new Generator($tapestry->getContainer()->get('Compile.Steps'), $tapestry); 29 | 30 | /** @var Project $project */ 31 | $project = $tapestry->getContainer()->get(Project::class); 32 | $project->set('cmd_options', []); 33 | $generator->generate($project, new NullOutput); 34 | // 35 | 36 | $this->assertTrue($project->has('compiled')); 37 | $this->assertInstanceOf(FlatCollection::class, $project->get('compiled')); 38 | 39 | /** @var FlatCollection $compiledFiles */ 40 | $compiledFiles = $project->get('compiled'); 41 | $this->assertEquals(7, $compiledFiles->count()); 42 | $this->assertTrue(isset($compiledFiles['blog_categories_category_phtml_misc'])); 43 | $this->assertInstanceOf(FileWriter::class, $compiledFiles['blog_categories_category_phtml_misc']); 44 | 45 | /** @var FileWriter $miscCategory */ 46 | $miscCategory = $compiledFiles['blog_categories_category_phtml_misc']; 47 | $miscCategoryFile = $miscCategory->getFile(); 48 | 49 | $this->assertInstanceOf(File::class, $miscCategoryFile); 50 | $this->assertTrue($miscCategoryFile->hasData('blog_categories_items')); 51 | $this->assertTrue($miscCategoryFile->hasData('blog_categories')); 52 | 53 | $this->assertEquals(['misc', 'first-post'], $miscCategoryFile->getData('blog_categories', [])); 54 | $this->assertEquals('misc', $miscCategoryFile->getData('taxonomyName', '')); 55 | 56 | /** @var FileWriter $index */ 57 | $index = $compiledFiles['index_phtml']; 58 | $indexFile = $index->getFile(); 59 | 60 | $this->assertTrue($indexFile->hasData('blog_categories_items')); 61 | $this->assertTrue($indexFile->hasData('blog_items')); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Traits/MockFile.php: -------------------------------------------------------------------------------- 1 | getRelativePath($base, $filePath), $this->getRelativePath($base, $filePath))); 48 | $frontMatter = new FrontMatter($file->getFileContent()); 49 | $file->setData($frontMatter->getData()); 50 | $file->setContent($frontMatter->getContent()); 51 | $file->getUid(); // Force the file to generate its uid 52 | return $file; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Traits/MockTapestry.php: -------------------------------------------------------------------------------- 1 | $siteDir, 28 | '--env' => $environment 29 | ], $definitions)); 30 | 31 | if (is_array($configuration)) { 32 | $tapestry->getContainer()->add(Configuration::class, new Configuration($configuration)); 33 | } 34 | 35 | return $tapestry; 36 | } 37 | } -------------------------------------------------------------------------------- /tests/Traits/MockViewFile.php: -------------------------------------------------------------------------------- 1 | getFileContent()); 20 | $file->setData($frontMatter->getData()); 21 | $file->setContent($frontMatter->getContent()); 22 | 23 | /** @var Project $project */ 24 | $project = $tapestry->getContainer()->get(Project::class); 25 | 26 | if ($render === true) { 27 | /** @var ContentRendererFactory $contentRenderers */ 28 | $contentRendererFactory = new ContentRendererFactory(); 29 | /** @var Configuration::class $configuration */ 30 | $configuration = $tapestry->getContainer()->get(Configuration::class); 31 | foreach ($configuration->get('content_renderers') as $renderer) { 32 | $contentRendererFactory->add($tapestry->getContainer()->get($renderer)); 33 | } 34 | $contentRendererFactory->renderFile($file); 35 | } 36 | 37 | $project->set('compiled', [ 38 | $file->getUid() => $file, 39 | ]); 40 | 41 | return new ViewFile($project, $file->getUid()); 42 | } 43 | } -------------------------------------------------------------------------------- /tests/UnPublishDraftsTest.php: -------------------------------------------------------------------------------- 1 | copyDirectory('assets/build_test_12/src', '_tmp'); 16 | $output = $this->runCommand('build', '--quiet --auto-publish'); 17 | 18 | $this->assertEquals('', trim($output->getDisplay())); 19 | $this->assertEquals(0, $output->getStatusCode()); 20 | 21 | $this->assertFileExists(__DIR__.'/_tmp/build_local/blog/2016/test-blog-entry-two/index.html'); 22 | } 23 | 24 | /** 25 | * Test that setting draft to true in a blog posts front matter ensures that it is not published. 26 | */ 27 | public function testUnpublishDrafts() 28 | { 29 | $this->copyDirectory('assets/build_test_12/src', '_tmp'); 30 | 31 | $output = $this->runCommand('build', '--quiet'); 32 | 33 | $this->assertEquals('', trim($output->getDisplay())); 34 | $this->assertEquals(0, $output->getStatusCode()); 35 | 36 | $this->assertFileEquals( 37 | __DIR__.'/assets/build_test_12/check/blog/2016/test-blog-entry.html', 38 | __DIR__.'/_tmp/build_local/blog/2016/test-blog-entry/index.html', 39 | '', 40 | true 41 | ); 42 | $this->assertFileNotExists(__DIR__.'/_tmp/build_local/blog/2016/test-blog-entry-two/index.html'); 43 | $this->assertFileNotExists(__DIR__.'/_tmp/build_local/blog/2116/test-blog-entry-three/index.html'); 44 | } 45 | 46 | /** 47 | * Test Configuration. 48 | */ 49 | public function testPublishDraftsConfigurationOverride() 50 | { 51 | $this->copyDirectory('assets/build_test_13/src', '_tmp'); 52 | 53 | $output = $this->runCommand('build', '--quiet'); 54 | 55 | $this->assertEquals('', trim($output->getDisplay())); 56 | $this->assertEquals(0, $output->getStatusCode()); 57 | 58 | $this->assertFileEquals( 59 | __DIR__.'/assets/build_test_13/check/blog/2016/test-blog-entry.html', 60 | __DIR__.'/_tmp/build_local/blog/2016/test-blog-entry/index.html', 61 | '', 62 | true 63 | ); 64 | 65 | $this->assertFileEquals( 66 | __DIR__.'/assets/build_test_13/check/blog/2016/test-blog-entry-two.html', 67 | __DIR__.'/_tmp/build_local/blog/2016/test-blog-entry-two/index.html', 68 | '', 69 | true 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/assets/build_test_1/check/about.html: -------------------------------------------------------------------------------- 1 |

Hello world!

-------------------------------------------------------------------------------- /tests/assets/build_test_1/check/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_1/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteOne\TestKernel::class, 6 | 'pretty_permalink' => false, 7 | ]; 8 | -------------------------------------------------------------------------------- /tests/assets/build_test_1/src/kernel.php: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /tests/assets/build_test_10/src/TestKernelCommand.php: -------------------------------------------------------------------------------- 1 | setName('hello') 15 | ->setDescription('Hello World From A Kernel Loaded Command'); 16 | } 17 | 18 | /** 19 | * @return int 20 | */ 21 | protected function fire() 22 | { 23 | $this->info('Hello world! This command was loaded via a site Kernel.'); 24 | 25 | return 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/assets/build_test_10/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteTen\Kernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_10/src/kernel.php: -------------------------------------------------------------------------------- 1 | tapestry = Tapestry::getInstance(); 18 | } 19 | 20 | public function register() 21 | { 22 | // Not the ideal way of adding the file, but this a test so auto-loading is not necessary :) 23 | include __DIR__.'/TestKernelCommand.php'; 24 | 25 | /** @var \Tapestry\Console\Application $cliApplication */ 26 | $cliApplication = $this->tapestry->getContainer()->get(\Tapestry\Console\Application::class); 27 | $cliApplication->add(new TestKernelCommand()); 28 | } 29 | 30 | public function boot() 31 | { 32 | // ... 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/assets/build_test_11/check/blog/2016/test-blog-entry-two.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is another test blog entry 6 | 7 | 8 |

This is a test posting

9 | 10 |

Something goes here...

11 | 12 | -------------------------------------------------------------------------------- /tests/assets/build_test_11/check/blog/2016/test-blog-entry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a test blog entry 6 | 7 | 8 |

This is a test posting

9 | 10 |

Test, Test, Test...

11 | 12 | -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/source/_blog/2016-03-10-test-blog-entry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is a test blog entry 3 | --- 4 | 5 | # This is a test posting 6 | 7 | Test, Test, Test... -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/source/_blog/2016-03-11-test-blog-entry-two.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is another test blog entry 3 | --- 4 | 5 | # This is a test posting 6 | 7 | Something goes here... -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= (isset($title) ? ($title) : 'Unknown'); ?> 6 | 7 | 8 | section('content') ?> 9 | 10 | -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | layout('_templates/default', ['title' => $title]); ?> 2 | getContent() ?> -------------------------------------------------------------------------------- /tests/assets/build_test_11/src/source/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_12/check/blog/2016/test-blog-entry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a test blog entry 6 | 7 | 8 | 9 |

This is a test posting

10 | 11 |

Test, Test, Test...

12 | 13 | -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/source/_blog/2016-03-10-test-blog-entry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is a test blog entry 3 | --- 4 | 5 | # This is a test posting 6 | 7 | Test, Test, Test... -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/source/_blog/2016-03-11-test-blog-entry-two.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is another test blog entry 3 | draft: true 4 | --- 5 | 6 | # This is a test posting 7 | 8 | Something goes here... -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/source/_blog/2116-03-11-test-blog-entry-three.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is a scheduled post 3 | draft: false 4 | --- 5 | 6 | # This is a test posting 7 | 8 | Something goes here... -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= (isset($title) ? $title : ''); ?> 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/assets/build_test_12/src/source/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_13/check/blog/2016/test-blog-entry-two.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is another test blog entry 6 | 7 | 8 | 9 |

This is a test posting

10 | 11 |

Something goes here...

12 | 13 | -------------------------------------------------------------------------------- /tests/assets/build_test_13/check/blog/2016/test-blog-entry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a test blog entry 6 | 7 | 8 | 9 |

This is a test posting

10 | 11 |

Test, Test, Test...

12 | 13 | -------------------------------------------------------------------------------- /tests/assets/build_test_13/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'publish_drafts' => true, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_13/src/source/_blog/2016-03-10-test-blog-entry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is a test blog entry 3 | --- 4 | 5 | # This is a test posting 6 | 7 | Test, Test, Test... -------------------------------------------------------------------------------- /tests/assets/build_test_13/src/source/_blog/2016-03-11-test-blog-entry-two.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: This is another test blog entry 3 | draft: true 4 | --- 5 | 6 | # This is a test posting 7 | 8 | Something goes here... -------------------------------------------------------------------------------- /tests/assets/build_test_13/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= (isset($title) ? $title : ''); ?> 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/assets/build_test_13/src/source/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_14/check/default_index.html: -------------------------------------------------------------------------------- 1 | Default Environment -------------------------------------------------------------------------------- /tests/assets/build_test_14/check/development_index.html: -------------------------------------------------------------------------------- 1 | Development Environment -------------------------------------------------------------------------------- /tests/assets/build_test_14/src/config-development.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'site' => [ 6 | 'environment_test' => 'Development Environment', 7 | ], 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_14/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'site' => [ 6 | 'environment_test' => 'Default Environment', 7 | ], 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_14/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | site('environment_test'); ?> -------------------------------------------------------------------------------- /tests/assets/build_test_15/check/draft-false.html: -------------------------------------------------------------------------------- 1 | isNotDraft -------------------------------------------------------------------------------- /tests/assets/build_test_15/check/draft-true.html: -------------------------------------------------------------------------------- 1 | isDraft -------------------------------------------------------------------------------- /tests/assets/build_test_15/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'publish_drafts' => true, 6 | 'pretty_permalink' => false, 7 | ]; 8 | -------------------------------------------------------------------------------- /tests/assets/build_test_15/src/source/draft-false.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | draft: false 3 | --- 4 | isDraft() ? 'isDraft' : 'isNotDraft') ?> -------------------------------------------------------------------------------- /tests/assets/build_test_15/src/source/draft-true.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | draft: true 3 | --- 4 | isDraft() ? 'isDraft' : 'isNotDraft') ?> -------------------------------------------------------------------------------- /tests/assets/build_test_16/check/index.html: -------------------------------------------------------------------------------- 1 | _blog_2016-08-22-no-categories_md : Categories : isSet 2 | _blog_2016-08-22-no-categories_md : Tags : isSet 3 | _blog_2015-08-22-first-post_md : Categories : isSet 4 | _blog_2015-08-22-first-post_md : Tags : isSet -------------------------------------------------------------------------------- /tests/assets/build_test_16/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'pretty_permalink' => false, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_16/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | --- 7 | 8 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_16/src/source/_blog/2016-08-22-no-categories.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: No Categories 3 | --- 4 | 5 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_16/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: My Website 3 | use: 4 | - blog 5 | --- 6 | 7 | getFile()->getUid() . ' : Categories : ' . (is_null($item->getData('categories')) ? 'isNotSet' : 'isSet') . "\n"; 11 | echo $item->getFile()->getUid() . ' : Tags : ' . (is_null($item->getData('tags')) ? 'isNotSet' : 'isSet') . "\n"; 12 | } 13 | ?> 14 | -------------------------------------------------------------------------------- /tests/assets/build_test_17/check/1.html: -------------------------------------------------------------------------------- 1 | next : blog_index_phtml_page_2 2 | prev : 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_17/check/2.html: -------------------------------------------------------------------------------- 1 | next : 2 | prev : blog_index_phtml 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | --- 7 | 8 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/_blog/2015-08-23-second-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Second Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/_blog/2015-08-24-third-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Third Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/_blog/2015-08-25-fourth-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fourth Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/blog/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog Archive 3 | use: 4 | - blog 5 | - blog_categories 6 | generator: 7 | - PaginationGenerator 8 | pagination: 9 | provider: blog 10 | perPage: 3 11 | --- 12 | getNext()) ? '' : $pagination->getNext()->getFile()->getUid()) . "\n"; 19 | echo 'prev : ' . (is_null($pagination->getPrevious()) ? '' : $pagination->getPrevious()->getFile()->getUid()) . "\n"; 20 | 21 | ?> 22 | -------------------------------------------------------------------------------- /tests/assets/build_test_17/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: My Website 3 | use: 4 | - blog 5 | --- 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/check/first-post.html: -------------------------------------------------------------------------------- 1 | prev : isNull 2 | next : Second Post 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/check/fourth-post.html: -------------------------------------------------------------------------------- 1 | prev : Third Post 2 | next : isNull 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/check/second-post.html: -------------------------------------------------------------------------------- 1 | prev : First Post 2 | next : Third Post 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/check/third-post.html: -------------------------------------------------------------------------------- 1 | prev : Second Post 2 | next : Fourth Post 3 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | --- 7 | 8 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/_blog/2015-08-23-second-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Second Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/_blog/2015-08-24-third-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Third Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/_blog/2015-08-25-fourth-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fourth Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | generator: 3 | - CollectionItemGenerator 4 | --- 5 | getPrevious()) ? 'isNull' : $previous_next->getPrevious()->getData('title')) . "\n"; 13 | echo 'next : ' . (is_null($previous_next->getNext()) ? 'isNull' : $previous_next->getNext()->getData('title')) . "\n"; 14 | } -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/blog/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog Archive 3 | use: 4 | - blog 5 | - blog_categories 6 | generator: 7 | - PaginationGenerator 8 | pagination: 9 | provider: blog 10 | perPage: 3 11 | --- 12 | getNext()) ? '' : $pagination->getNext()->getFile()->getUid()) . "\n"; 19 | echo 'prev : ' . (is_null($pagination->getPrevious()) ? '' : $pagination->getPrevious()->getFile()->getUid()) . "\n"; 20 | 21 | ?> 22 | -------------------------------------------------------------------------------- /tests/assets/build_test_18/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: My Website 3 | use: 4 | - blog 5 | --- 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_19/check/test.html: -------------------------------------------------------------------------------- 1 |

Test

2 |
3 |

Test Content

4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_19/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_19/src/source/_templates/page.phtml: -------------------------------------------------------------------------------- 1 |

2 |
3 | section('content') ?> 4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_19/src/source/test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Test" 4 | --- 5 | 6 | Test Content -------------------------------------------------------------------------------- /tests/assets/build_test_2/check/about.html: -------------------------------------------------------------------------------- 1 |

Hello world!

-------------------------------------------------------------------------------- /tests/assets/build_test_2/check/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | testVar: Hello world 3 | --- 4 |

-------------------------------------------------------------------------------- /tests/assets/build_test_2/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteTwo\TestKernel::class, 6 | 'pretty_permalink' => false, 7 | ]; 8 | -------------------------------------------------------------------------------- /tests/assets/build_test_2/src/kernel.php: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /tests/assets/build_test_20/check/test.html: -------------------------------------------------------------------------------- 1 |
2 |

Test

3 |
4 |

Test Content

5 |
6 |
-------------------------------------------------------------------------------- /tests/assets/build_test_20/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_20/src/source/_templates/child.phtml: -------------------------------------------------------------------------------- 1 | layout('_templates/page'); ?> 6 |

7 |
8 | getContent() ?> 9 |
-------------------------------------------------------------------------------- /tests/assets/build_test_20/src/source/_templates/page.phtml: -------------------------------------------------------------------------------- 1 |
2 | section('content') ?> 3 | 4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_20/src/source/test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: child 3 | title: "Test" 4 | --- 5 | 6 | Test Content -------------------------------------------------------------------------------- /tests/assets/build_test_21/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteTwentyOne\TestKernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_21/src/kernel.php: -------------------------------------------------------------------------------- 1 | true, 5 | 'kernel' => \SiteTwentyOne\TestKernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_21/src_replace/kernel.php: -------------------------------------------------------------------------------- 1 | Test 2 |
3 |

Test Content

4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_22/check/index_replace.html: -------------------------------------------------------------------------------- 1 |

Test

2 |
3 |

Test Content

4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_22/check/multi-inheritance.html: -------------------------------------------------------------------------------- 1 |

Inheritance Test

2 |
3 |

Test Content

4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_22/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_22/src/source/_templates/inheritance-test.phtml: -------------------------------------------------------------------------------- 1 | layout('_templates/page', ['title' => $title]); ?> 2 | getContent() ?> -------------------------------------------------------------------------------- /tests/assets/build_test_22/src/source/_templates/page.phtml: -------------------------------------------------------------------------------- 1 |

2 |
3 | section('content') ?> 4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_22/src/source/multi-inheritance-test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: inheritance-test 3 | title: "Inheritance Test" 4 | --- 5 | 6 | Test Content -------------------------------------------------------------------------------- /tests/assets/build_test_22/src/source/test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Test" 4 | --- 5 | 6 | Test Content -------------------------------------------------------------------------------- /tests/assets/build_test_22/src_replace/page.phtml: -------------------------------------------------------------------------------- 1 |

2 |
3 | section('content') ?> 4 |
-------------------------------------------------------------------------------- /tests/assets/build_test_23/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | --- 7 | 8 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/_blog/2015-08-23-second-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Second Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/_blog/2015-08-24-third-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Third Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/_blog/2015-08-25-fourth-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fourth Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/blog/categories/category.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Category Archive 3 | use: 4 | - blog_categories 5 | generator: 6 | - TaxonomyArchiveGenerator 7 | --- 8 | 9 | 16 | -------------------------------------------------------------------------------- /tests/assets/build_test_23/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | use: 4 | - blog 5 | - blog_categories 6 | --- 7 | 8 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_24/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | date: 1487262149 7 | --- 8 | 9 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/_blog/2015-08-23-second-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Second Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/_blog/2015-08-24-third-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Third Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/_blog/2015-08-25-fourth-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fourth Post 3 | categories: 4 | - misc 5 | --- 6 | 7 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/blog/categories/category.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Category Archive 3 | use: 4 | - blog_categories 5 | generator: 6 | - TaxonomyArchiveGenerator 7 | --- 8 | 9 | 16 | -------------------------------------------------------------------------------- /tests/assets/build_test_24/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | use: 4 | - blog 5 | - blog_categories 6 | --- 7 | 8 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_25/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_25/src/source/_blog/2015-08-22-first-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | categories: 4 | - misc 5 | - first post 6 | date: abc 7 | --- 8 | 9 | This is some test text. -------------------------------------------------------------------------------- /tests/assets/build_test_25/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | use: 4 | - blog 5 | - blog_categories 6 | --- 7 | 8 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_26/check/development_index.html: -------------------------------------------------------------------------------- 1 | Development Environment -------------------------------------------------------------------------------- /tests/assets/build_test_26/check/index.html: -------------------------------------------------------------------------------- 1 | Default Environment -------------------------------------------------------------------------------- /tests/assets/build_test_26/src/config-development.yaml: -------------------------------------------------------------------------------- 1 | debug: false 2 | site: 3 | environment_test: 'Development Environment' -------------------------------------------------------------------------------- /tests/assets/build_test_26/src/config.yaml: -------------------------------------------------------------------------------- 1 | debug: false 2 | site: 3 | environment_test: 'Default Environment' -------------------------------------------------------------------------------- /tests/assets/build_test_26/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | site('environment_test'); ?> -------------------------------------------------------------------------------- /tests/assets/build_test_27/check/development_index.html: -------------------------------------------------------------------------------- 1 | Development Environment -------------------------------------------------------------------------------- /tests/assets/build_test_27/check/index.html: -------------------------------------------------------------------------------- 1 | Default Environment -------------------------------------------------------------------------------- /tests/assets/build_test_27/src/config-development.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'site' => [ 6 | 'environment_test' => 'Development Environment', 7 | ], 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_27/src/config-development.yaml: -------------------------------------------------------------------------------- 1 | debug: false 2 | site: 3 | environment_test: 'Development Environment' -------------------------------------------------------------------------------- /tests/assets/build_test_27/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'site' => [ 6 | 'environment_test' => 'Default Environment', 7 | ], 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_27/src/config.yaml: -------------------------------------------------------------------------------- 1 | debug: false 2 | site: 3 | environment_test: 'Default Environment' -------------------------------------------------------------------------------- /tests/assets/build_test_27/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | site('environment_test'); ?> -------------------------------------------------------------------------------- /tests/assets/build_test_28/check/index.html: -------------------------------------------------------------------------------- 1 | hello world! 2 | -------------------------------------------------------------------------------- /tests/assets/build_test_28/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteTwentyEight\Kernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_28/src/kernel.php: -------------------------------------------------------------------------------- 1 | tapestry = Tapestry::getInstance(); 20 | } 21 | 22 | /** 23 | * This method is executed by Tapestry when the Kernel is registered. 24 | * 25 | * @return void 26 | */ 27 | public function register() 28 | { 29 | include (__DIR__ . '/lib/TestPlatesExtension.php'); 30 | 31 | /** @var Engine $engine */ 32 | $engine = $this->tapestry->getContainer()->get(Engine::class); 33 | $engine->loadExtension($this->tapestry->getContainer()->get(TestPlatesExtension::class)); 34 | } 35 | 36 | /** 37 | * This method of executed by Tapestry as part of the build process. 38 | * 39 | * @return void 40 | */ 41 | public function boot() 42 | { 43 | // ... 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/assets/build_test_28/src/lib/TestPlatesExtension.php: -------------------------------------------------------------------------------- 1 | registerFunction('test', [$this, 'test']); 11 | } 12 | 13 | public function test() 14 | { 15 | return 'hello world!'; 16 | } 17 | } -------------------------------------------------------------------------------- /tests/assets/build_test_28/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | test() ?> -------------------------------------------------------------------------------- /tests/assets/build_test_29/check/index.html: -------------------------------------------------------------------------------- 1 | PHP -> HTML Working 2 | -------------------------------------------------------------------------------- /tests/assets/build_test_29/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'site' => [ 6 | 'name' => 'PHP -> HTML Working' 7 | ] 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_29/src/source/index.php: -------------------------------------------------------------------------------- 1 | site('name') ?> -------------------------------------------------------------------------------- /tests/assets/build_test_3/check/about.html: -------------------------------------------------------------------------------- 1 |

About Page

-------------------------------------------------------------------------------- /tests/assets/build_test_3/check/index.html: -------------------------------------------------------------------------------- 1 |

Hello world!

-------------------------------------------------------------------------------- /tests/assets/build_test_3/check/not-pretty.html: -------------------------------------------------------------------------------- 1 |

Not Pretty

-------------------------------------------------------------------------------- /tests/assets/build_test_3/src/config.php: -------------------------------------------------------------------------------- 1 | true, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_3/src/source/about.md: -------------------------------------------------------------------------------- 1 | # About Page -------------------------------------------------------------------------------- /tests/assets/build_test_3/src/source/index.md: -------------------------------------------------------------------------------- 1 | # Hello world! -------------------------------------------------------------------------------- /tests/assets/build_test_3/src/source/not-pretty.md: -------------------------------------------------------------------------------- 1 | --- 2 | pretty_permalink: false 3 | --- 4 | # Not Pretty -------------------------------------------------------------------------------- /tests/assets/build_test_30/src/config.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_30/src/source/_should-not-exist/index.html: -------------------------------------------------------------------------------- 1 | This should not exist. -------------------------------------------------------------------------------- /tests/assets/build_test_30/src/source/index.php: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /tests/assets/build_test_30/src/source/should-exist/_should-not-exist/index.html: -------------------------------------------------------------------------------- 1 | This should not exist. -------------------------------------------------------------------------------- /tests/assets/build_test_30/src/source/should-exist/index.html: -------------------------------------------------------------------------------- 1 | This should exist -------------------------------------------------------------------------------- /tests/assets/build_test_31/check/base.html: -------------------------------------------------------------------------------- 1 | !!! default.phtml 2 | base_phtml 3 | !!! ./default.phtml 4 | !!! base.phtml 5 | base_phtml 6 | !!! ./base.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_31/check/blog.html: -------------------------------------------------------------------------------- 1 | !!! default.phtml 2 | _blog_2016-04-18-test_md 3 | !!! ./default.phtml 4 | !!! blog.phtml 5 | _blog_2016-04-18-test_md 6 |

!!! 2016-04-18-test.md 7 | Hello World! 8 | !!! ./2016-04-18-test.md

9 | !!! ./blog.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_31/check/page-multi.html: -------------------------------------------------------------------------------- 1 | !!! default.phtml 2 | page-multi_md 3 | !!! ./default.phtml 4 | !!! page.phtml 5 | page-multi_md 6 | !!! ./page.phtml 7 |

!!! page-multi.md

8 | 9 |

Single Page

10 | 11 |

!!! ./page-multi.md

12 | -------------------------------------------------------------------------------- /tests/assets/build_test_31/check/page.html: -------------------------------------------------------------------------------- 1 | !!! default.phtml 2 | page_md 3 | !!! ./default.phtml 4 |

!!! page.md

5 | 6 |

Single Page

7 | 8 |

!!! ./page.md

9 | -------------------------------------------------------------------------------- /tests/assets/build_test_31/check/single.html: -------------------------------------------------------------------------------- 1 | !!! single.phtml 2 | single_phtml 3 | !!! ./single.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/config.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/_blog/2016-04-18-test.md: -------------------------------------------------------------------------------- 1 | !!! 2016-04-18-test.md 2 | Hello World! 3 | !!! ./2016-04-18-test.md -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | !!! default.phtml 2 | getFile()) ? 'null' : $this->getFile()->getUid()) . "\n" ?> 3 | !!! ./default.phtml 4 | section('content') ?> -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/_templates/page.phtml: -------------------------------------------------------------------------------- 1 | layout('_templates/default'); 9 | ?> 10 | !!! page.phtml 11 | getFile()) ? 'null' : $this->getFile()->getUid()) . "\n" ?> 12 | !!! ./page.phtml 13 | section('content') ?> 14 | -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | !!! blog.phtml 5 | getFile()) ? 'null' : $this->getFile()->getUid()) . "\n" ?> 6 | getContent() ?> 7 | !!! ./blog.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/base.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | !!! base.phtml 5 | getFile()) ? 'null' : $this->getFile()->getUid()) . "\n" ?> 6 | !!! ./base.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/page-multi.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Multi Inheritance" 4 | --- 5 | !!! page-multi.md 6 | #Single Page 7 | !!! ./page-multi.md -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "Single Inheritance" 4 | --- 5 | !!! page.md 6 | #Single Page 7 | !!! ./page.md -------------------------------------------------------------------------------- /tests/assets/build_test_31/src/source/single.phtml: -------------------------------------------------------------------------------- 1 | !!! single.phtml 2 | getFile()) ? 'null' : $this->getFile()->getUid()) . "\n" ?> 3 | !!! ./single.phtml -------------------------------------------------------------------------------- /tests/assets/build_test_32/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'copy' => [ 6 | 'js' 7 | ] 8 | ]; 9 | -------------------------------------------------------------------------------- /tests/assets/build_test_32/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | Hello World -------------------------------------------------------------------------------- /tests/assets/build_test_33/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 6 | 'content_types' => [ 7 | 'blog' => [ 8 | 'permalink' => 'blog/{year}/{category}/{slug}.html', 9 | ], 10 | ], 11 | ]; 12 | -------------------------------------------------------------------------------- /tests/assets/build_test_33/src/source/_blog/2016-04-18-test.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test 3 | categories: 4 | - category-1 5 | - category two 6 | - category III 7 | --- 8 | Hello world! -------------------------------------------------------------------------------- /tests/assets/build_test_33/src/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | section('content') ?> -------------------------------------------------------------------------------- /tests/assets/build_test_33/src/source/_views/blog.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | getContent() ?> -------------------------------------------------------------------------------- /tests/assets/build_test_34/src/source/_templates/test-template.phtml: -------------------------------------------------------------------------------- 1 |

Test

2 |

-------------------------------------------------------------------------------- /tests/assets/build_test_34/src/source/test.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: test page 3 | template: test-template 4 | --- 5 | Hello World -------------------------------------------------------------------------------- /tests/assets/build_test_35/src/source/abc.123.xyz.html: -------------------------------------------------------------------------------- 1 | Hello World -------------------------------------------------------------------------------- /tests/assets/build_test_35/src/source/css/main.min.css: -------------------------------------------------------------------------------- 1 | hello:before{ 2 | content: "world!"; 3 | } -------------------------------------------------------------------------------- /tests/assets/build_test_36/src/source/file-a.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: file-clash.html 3 | --- 4 | Hello world from File A -------------------------------------------------------------------------------- /tests/assets/build_test_36/src/source/file-b.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: file-clash.html 3 | --- 4 | Hello world from File B -------------------------------------------------------------------------------- /tests/assets/build_test_37/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteThirtySeven\Kernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_37/src/kernel.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteThirtyEight\Kernel::class, 6 | ]; 7 | -------------------------------------------------------------------------------- /tests/assets/build_test_39/src/source/default.css: -------------------------------------------------------------------------------- 1 | .hello{ 2 | color: red; 3 | } -------------------------------------------------------------------------------- /tests/assets/build_test_39/src/source/default.min.css: -------------------------------------------------------------------------------- 1 | .hello{color: red;} -------------------------------------------------------------------------------- /tests/assets/build_test_39/src/source/default.min.css.map: -------------------------------------------------------------------------------- 1 | .hello{color: red;} -------------------------------------------------------------------------------- /tests/assets/build_test_4/check/about.html: -------------------------------------------------------------------------------- 1 |

Hello world!

-------------------------------------------------------------------------------- /tests/assets/build_test_4/check/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_4/src/config.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'ignored_folder', 6 | 'assets', 7 | ], 8 | 9 | 'copy' => [ 10 | 'assets', 11 | ], 12 | ]; 13 | -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= $title . ' — ' . $this->site['title']; ?> 6 | 7 | 8 | 9 | 10 | 11 |

Tapestry Scaffold

12 |
Congratulations you have successfully scaffolded your first tapestry site.
13 | 14 | -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | key: value 3 | --- 4 | # Hello world! -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/assets/js/app.js: -------------------------------------------------------------------------------- 1 | var n = 42; -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/assets/js/something_else/a.js: -------------------------------------------------------------------------------- 1 | var a = 42; -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/assets/js/something_else/b.js: -------------------------------------------------------------------------------- 1 | var b = 42; -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/ignored_folder/should_be_ignored.md: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_4/src/source/index.php: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /tests/assets/build_test_40/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | ]; 6 | -------------------------------------------------------------------------------- /tests/assets/build_test_40/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | Hello World -------------------------------------------------------------------------------- /tests/assets/build_test_5/check/about.html: -------------------------------------------------------------------------------- 1 |

Hello world!

-------------------------------------------------------------------------------- /tests/assets/build_test_5/check/index.html: -------------------------------------------------------------------------------- 1 |

Hello world

-------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/a_folder/a_file.md: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/a_folder/another_file.md: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/a_folder/b_folder/b_file.md: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | key: value 3 | --- 4 | # Hello world! -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/b_folder/b_file_2.md: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/b_folder/b_file_3.md: -------------------------------------------------------------------------------- 1 | --- 2 | pretty_permalink: false 3 | --- 4 | Test -------------------------------------------------------------------------------- /tests/assets/build_test_5/src/source/index.php: -------------------------------------------------------------------------------- 1 |

-------------------------------------------------------------------------------- /tests/assets/build_test_6/check/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is the page title 6 | 7 | 8 | 9 |

Hello world!

10 |

This is the page content...

11 |

This is array item one

12 |

This is array item two

13 |

This is array item three

14 | 15 | -------------------------------------------------------------------------------- /tests/assets/build_test_6/src/source/_templates/default.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= $title; ?> 6 | 7 | 8 | 9 | section('content') ?> 10 | 11 |

12 |

13 |

14 | 15 | -------------------------------------------------------------------------------- /tests/assets/build_test_6/src/source/index.phtml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: This is the page title 4 | var_one: 5 | - This is array item one 6 | - This is array item two 7 | - This is array item three 8 | --- 9 | 10 |

Hello world!

11 |

This is the page content...

-------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/aaa.md: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /about 3 | --- 4 | 5 | An about page... -------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | year: "2016" 3 | month: "02" 4 | permalink: /blog/{year}/{month}/test.html 5 | --- 6 | 7 | Blog stuff... -------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/else.md: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /rah.html 3 | --- 4 | 5 | Something Else... -------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /123/abc/file.xml 3 | --- 4 | 5 | Testing 1-2-1-2... -------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/something.html: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /abc/123/file.html 3 | --- 4 | 5 | Else Something... -------------------------------------------------------------------------------- /tests/assets/build_test_7/src/source/testy.md: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /test/testing/testy 3 | --- 4 | 5 | Blah -------------------------------------------------------------------------------- /tests/assets/build_test_8/check/boot.html: -------------------------------------------------------------------------------- 1 |

Kernel Booting Works

-------------------------------------------------------------------------------- /tests/assets/build_test_8/check/register.html: -------------------------------------------------------------------------------- 1 |

Kernel Registering Works

-------------------------------------------------------------------------------- /tests/assets/build_test_8/src/config.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'kernel' => \SiteEight\Kernel::class, 6 | 'pretty_permalink' => false, 7 | ]; 8 | -------------------------------------------------------------------------------- /tests/assets/build_test_8/src/kernel.php: -------------------------------------------------------------------------------- 1 | tapestry = Tapestry::getInstance(); 19 | } 20 | 21 | public function register() 22 | { 23 | $this->tapestry->getContainer()->get(Configuration::class)->set('site.kernel_register_works', 24 | 'Kernel Registering Works'); 25 | } 26 | 27 | public function boot() 28 | { 29 | $this->tapestry->getContainer()->get(Configuration::class)->set('site.kernel_boot_works', 30 | 'Kernel Booting Works'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/assets/build_test_8/src/source/boot.phtml: -------------------------------------------------------------------------------- 1 |

site('kernel_boot_works'); ?>

-------------------------------------------------------------------------------- /tests/assets/build_test_8/src/source/register.phtml: -------------------------------------------------------------------------------- 1 |

site('kernel_register_works'); ?>

-------------------------------------------------------------------------------- /tests/assets/cache_files/.local_cache.1.0.10: -------------------------------------------------------------------------------- 1 | O:28:"Tapestry\Entities\CacheStore":2:{s:35:"Tapestry\Entities\CacheStoreitems";a:5:{s:12:"single_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:12:"single_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"dfe666596bb172b7f4121564e1b1e9e2b2be0185";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:0:{}}s:7:"page_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:7:"page_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:13:"page-multi_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:13:"page-multi_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"2d8bfae5be1ef7bb1b642a6f49c7fedc3ac572c8";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:2:{i:0;s:15:"_templates\page";i:1;s:18:"_templates/default";}}s:10:"base_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:10:"base_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:24:"_blog_2016-04-18-test_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:24:"_blog_2016-04-18-test_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}}s:34:"Tapestry\Entities\CacheStorehash";s:40:"9254d8c03b1d82993c158aa923a15faa8c968990";} -------------------------------------------------------------------------------- /tests/assets/cache_files/.local_cache.1.0.8: -------------------------------------------------------------------------------- 1 | O:28:"Tapestry\Entities\CacheStore":2:{s:35:"Tapestry\Entities\CacheStoreitems";a:5:{s:12:"single_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:12:"single_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"dfe666596bb172b7f4121564e1b1e9e2b2be0185";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:0:{}}s:7:"page_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:7:"page_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:13:"page-multi_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:13:"page-multi_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"2d8bfae5be1ef7bb1b642a6f49c7fedc3ac572c8";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:2:{i:0;s:15:"_templates\page";i:1;s:18:"_templates/default";}}s:10:"base_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:10:"base_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:24:"_blog_2016-04-18-test_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:24:"_blog_2016-04-18-test_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}}s:34:"Tapestry\Entities\CacheStorehash";s:40:"56157ae56f3acd71dd81a2d09e7582399c661599";} -------------------------------------------------------------------------------- /tests/assets/cache_files/.local_cache.1.0.9: -------------------------------------------------------------------------------- 1 | O:28:"Tapestry\Entities\CacheStore":2:{s:35:"Tapestry\Entities\CacheStoreitems";a:5:{s:12:"single_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:12:"single_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"dfe666596bb172b7f4121564e1b1e9e2b2be0185";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:0:{}}s:7:"page_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:7:"page_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:13:"page-multi_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:13:"page-multi_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"2d8bfae5be1ef7bb1b642a6f49c7fedc3ac572c8";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:2:{i:0;s:15:"_templates\page";i:1;s:18:"_templates/default";}}s:10:"base_phtml";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:10:"base_phtml";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}s:24:"_blog_2016-04-18-test_md";O:28:"Tapestry\Entities\CachedFile":4:{s:33:"Tapestry\Entities\CachedFileuid";s:24:"_blog_2016-04-18-test_md";s:34:"Tapestry\Entities\CachedFilehash";s:40:"8f69cb02e1b9308aa57f4998705243ede322d476";s:45:"Tapestry\Entities\CachedFilesourceDirectory";s:80:"C:\Users\simon\Documents\Projects\tapestry\tests\assets\build_test_31\src\source";s:37:"Tapestry\Entities\CachedFilelayouts";a:1:{i:0;s:18:"_templates\default";}}}s:34:"Tapestry\Entities\CacheStorehash";s:40:"f580e34e46e7e2ce49e3835c8a70f7bc81dc04b0";} -------------------------------------------------------------------------------- /tests/mocks/TestCategoryPermalinkTagLimitOne.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test md post" 3 | categories: 4 | - category1 5 | - category2 6 | - category3 7 | permalink: /{category,1}/{slug}/index.html 8 | --- 9 | Hello world! -------------------------------------------------------------------------------- /tests/mocks/TestCategoryPermalinkTagLimitTwo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test md post" 3 | categories: 4 | - category1 5 | - category2 6 | - category3 7 | permalink: /{category,2}/{slug}/index.html 8 | --- 9 | Hello world! --------------------------------------------------------------------------------