├── .gitignore ├── tests └── Dflydev │ └── Twig │ └── Extension │ └── Theme │ ├── fixtures │ └── non-typed-theme │ │ └── blue │ │ └── css │ │ └── main.css │ └── ThemeTwigExtensionTest.php ├── .travis.yml ├── phpunit.xml.dist ├── composer.json ├── LICENSE ├── src └── Dflydev │ └── Twig │ └── Extension │ └── Theme │ └── ThemeTwigExtension.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | -------------------------------------------------------------------------------- /tests/Dflydev/Twig/Extension/Theme/fixtures/non-typed-theme/blue/css/main.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3.3 5 | - 5.3 6 | - 5.4 7 | 8 | before_script: 9 | - wget -nc http://getcomposer.org/composer.phar 10 | - php composer.phar install --dev 11 | 12 | script: phpunit --coverage-text --verbose 13 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/Dflydev/Twig/Extension/Theme 6 | 7 | 8 | 9 | 10 | 11 | ./src/Dflydev/Twig/Extension/Theme/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dflydev/theme-twig-extension", 3 | "description": "Twig Extension for Theme", 4 | "keywords": ["theme", "twig", "extension"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Dragonfly Development Inc.", 9 | "email": "info@dflydev.com", 10 | "homepage": "http://dflydev.com" 11 | }, 12 | { 13 | "name": "Beau Simensen", 14 | "email": "beau@dflydev.com", 15 | "homepage": "http://beausimensen.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.3.3", 20 | "dflydev/theme": "1.*@dev", 21 | "twig/twig": "~1.9" 22 | }, 23 | "autoload": { 24 | "psr-0": { 25 | "Dflydev\\Twig\\Extension\\Theme": "src" 26 | } 27 | }, 28 | "extra": { 29 | "branch-alias": { 30 | "dev-master": "1.0-dev" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Dragonfly Development Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/Dflydev/Twig/Extension/Theme/ThemeTwigExtension.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class ThemeTwigExtension extends \Twig_Extension 22 | { 23 | /** 24 | * Constructor 25 | * 26 | * @param ResourceUrlGeneratorInterface $resourceUrlGenerator 27 | */ 28 | public function __construct(ResourceUrlGeneratorInterface $resourceUrlGenerator) 29 | { 30 | $this->resourceUrlGenerator = $resourceUrlGenerator; 31 | } 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function getFunctions() 36 | { 37 | return array( 38 | 'theme_resource' => new \Twig_Function_Method($this, 'generateResourceUrl'), 39 | ); 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function getName() 46 | { 47 | return 'theme'; 48 | } 49 | 50 | /** 51 | * Generate a URL for a Theme's resource 52 | * 53 | * @param string $resource 54 | * 55 | * @return string 56 | */ 57 | public function generateResourceUrl($resource) 58 | { 59 | return $this->resourceUrlGenerator->generateResourceUrl($resource); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Dflydev/Twig/Extension/Theme/ThemeTwigExtensionTest.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class ThemeTwigExtensionTest extends \PHPUnit_Framework_TestCase 20 | { 21 | protected function createThemeTwigExtensionWithDeps() 22 | { 23 | $resourceUrlGenerator = $this->getMock('Dflydev\Theme\ResourceUrlGenerator\ResourceUrlGeneratorInterface'); 24 | 25 | $themeTwigExtension = new ThemeTwigExtension($resourceUrlGenerator); 26 | 27 | return array($themeTwigExtension, $resourceUrlGenerator); 28 | } 29 | 30 | protected function createThemeTwigExtension() 31 | { 32 | $objects = $this->createThemeTwigExtensionWithDeps(); 33 | 34 | return $objects[0]; 35 | } 36 | 37 | /** 38 | * Test getName() 39 | */ 40 | public function testGetName() 41 | { 42 | $themeTwigExtension = $this->createThemeTwigExtension(); 43 | 44 | $this->assertEquals('theme', $themeTwigExtension->getName()); 45 | } 46 | 47 | /** 48 | * Test getFunctions() 49 | */ 50 | public function testGetFunctions() 51 | { 52 | $themeTwigExtension = $this->createThemeTwigExtension(); 53 | 54 | $functions = $themeTwigExtension->getFunctions(); 55 | $this->assertArrayHasKey('theme_resource', $functions); 56 | } 57 | 58 | /** 59 | * Test generateResourceUrl() 60 | */ 61 | public function testGenerateResourceUrl() 62 | { 63 | list($themeTwigExtension, $resourceUrlGenerator) = $this->createThemeTwigExtensionWithDeps(); 64 | 65 | $resourceUrlGenerator 66 | ->expects($this->once()) 67 | ->method('generateResourceUrl') 68 | ->with('css/main.css') 69 | ->will($this->returnValue('/url/path/to/css/main.css')); 70 | 71 | $this->assertEquals('/url/path/to/css/main.css', $themeTwigExtension->generateResourceUrl('css/main.css')); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Theme Twig Extension 2 | ==================== 3 | 4 | A [Theme][00] extension for [Twig][01]. 5 | 6 | 7 | Installation 8 | ------------ 9 | 10 | Through [Composer][00] as [dflydev/theme-twig-extension][01]. 11 | 12 | 13 | Usage 14 | ----- 15 | 16 | The following examples use the Symfony Routing implementation of 17 | `ResourceUrlGeneratorInterface`. 18 | 19 | ```php 20 | addExtension($themeTwigExtension); 38 | ``` 39 | 40 | Once enabled, Theme resources can be referenced by: 41 | 42 | {{ theme_resource('css/main.css') }} 43 | 44 | If `css/main.css` is accessible directly via the Theme instances docroot 45 | (as determined by the `PathMapperInterface`) then a URL to the public 46 | resource will be used. 47 | 48 | If `css/main.css` is *not* accessible directly, the `UrlGeneratorInterface` 49 | implementation will be used to generate a URL to the embedded Theme 50 | controllers. 51 | 52 | All implementations of `ResourceUrlGeneratorInterface` should follow the 53 | pattern of: 54 | 55 | 1. Checking to see if the resource is available publicly and 56 | using that if available. 57 | 2. Generating a fallback URL to expose non-public resources. 58 | 59 | 60 | ### Controller Requirements Example (Silex + Symfony Routing) 61 | 62 | * **_dflydev_typed_theme_handler**: 63 | Expects three params, `type`, `name`, and the `resource`. Name can be 64 | changed by calling `setTypedRouteName()`. 65 | 66 | Example: 67 | 68 | ```php 69 | get('/_theme_typed/{type}/{name}/resources/{resource}', function($type, $name, $resource) use ($app) { 71 | // do something to handle the theme request and return the 72 | // contents of the theme resource manually. 73 | }) 74 | ->assert('name', '.+') 75 | ->assert('resource', '.+') 76 | ->bind('_dflydev_typed_theme_handler'); 77 | ``` 78 | * **_dflydev_theme_handler**: 79 | Expects two params, `name` and the `resource`. Name can be changed by calling 80 | `setTypedRouteName()`. 81 | 82 | Example: 83 | 84 | ```php 85 | get('/_theme/{name}/resources/{resource}', function($name, $resource) use ($app) { 87 | // do something to handle the theme request and return the 88 | // contents of the theme resource manually. 89 | }) 90 | ->assert('name', '.+') 91 | ->assert('resource', '.+') 92 | ->bind('_dflydev_theme_handler'); 93 | ``` 94 | 95 | License 96 | ------- 97 | 98 | MIT, see LICENSE. 99 | 100 | 101 | Community 102 | --------- 103 | 104 | If you have questions or want to help out, join us in the 105 | [#dflydev][#dflydev] channel on irc.freenode.net. 106 | 107 | [00]: http://github.com/dflydev/dflydev-theme 108 | [01]: http://twig.sensiolabs.org/ 109 | [02]: http://getcomposer.org 110 | [03]: https://packagist.org/packages/dflydev/ant-path-matcher 111 | 112 | [#dflydev]: irc://irc.freenode.net/#dflydev 113 | --------------------------------------------------------------------------------