{"id":14983955,"url":"https://github.com/liip/liipthemebundle","last_synced_at":"2025-05-16T01:04:33.479Z","repository":{"id":56160188,"uuid":"1521381","full_name":"liip/LiipThemeBundle","owner":"liip","description":"Provides theming support for Symfony bundles","archived":false,"fork":false,"pushed_at":"2020-11-23T14:25:38.000Z","size":330,"stargazers_count":288,"open_issues_count":27,"forks_count":75,"subscribers_count":55,"default_branch":"master","last_synced_at":"2025-05-16T01:04:06.115Z","etag":null,"topics":["bundle","php","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-03-24T15:24:41.000Z","updated_at":"2025-03-15T20:58:00.000Z","dependencies_parsed_at":"2022-08-15T13:50:37.869Z","dependency_job_id":null,"html_url":"https://github.com/liip/LiipThemeBundle","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liip%2FLiipThemeBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liip%2FLiipThemeBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liip%2FLiipThemeBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liip%2FLiipThemeBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liip","download_url":"https://codeload.github.com/liip/LiipThemeBundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254448579,"owners_count":22072764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","php","symfony","symfony-bundle"],"created_at":"2024-09-24T14:08:14.145Z","updated_at":"2025-05-16T01:04:33.458Z","avatar_url":"https://github.com/liip.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Theme Bundle\n============\n\n\u003e This project is not longer maintained and recommends to use [SyliusThemeBundle](https://github.com/Sylius/SyliusThemeBundle) instead for support of Symfony 5 and Twig 3.\n\u003e For migration have a look at [Migrate to SyliusThemeBundle](#migrate-to-syliusthemebundle).\n\nThis bundle provides you the possibility to add themes to each bundle. In your\nbundle directory it will look under `Resources/themes/\u003cthemename\u003e` or fall back\nto the normal Resources/views if no matching file was found.\n\n[![Build Status](https://travis-ci.com/liip/LiipThemeBundle.svg?branch=master)](https://travis-ci.com/liip/LiipThemeBundle)\n\n## Installation\n\nInstallation is a quick (I promise!) 3 step process:\n\n1. Download LiipThemeBundle\n2. Enable the Bundle\n3. Import LiipThemeBundle routing\n\n### Step 1: Install LiipThemeBundle with composer\n\nRun the following composer require command:\n\n``` bash\n$ php composer.phar require liip/theme-bundle\n\n```\n\n### Step 2: Enable the bundle\n\nFinally, enable the bundle in the kernel:\n\n``` php\n\u003c?php\n// app/AppKernel.php\n\npublic function registerBundles()\n{\n    $bundles = array(\n        // ...\n        new Liip\\ThemeBundle\\LiipThemeBundle(),\n    );\n}\n```\n\n### Step 3: Import LiipThemeBundle routing files\n\nNow that you have activated and configured the bundle, all that is left to do is\nimport the LiipThemeBundle routing files.\n\nIn YAML:\n\n``` yaml\n# app/config/routing.yml\nliip_theme:\n    resource: \"@LiipThemeBundle/Resources/config/routing.xml\"\n    prefix: /theme\n```\n\nOr if you prefer XML:\n\n``` xml\n\u003c!-- app/config/routing.xml --\u003e\n\u003cimport resource=\"@LiipThemeBundle/Resources/config/routing.xml\" prefix=\"/theme\" /\u003e\n```\n\n## Configuration\n\nYou will have to set your possible themes and the currently active theme. It\nis required that the active theme is part of the themes list.\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    themes: ['standardTheme', 'winter_theme', 'weekend']\n    active_theme: 'standardTheme'\n```\n\n### Device specific themes/templates\n\nYou can provide specific themes or even templates for different devices (like: desktop, tablet, phone, plain). Set option ```autodetect_theme``` to true for setting ```current_device``` parameter based on the user agent:\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    autodetect_theme: true\n```\n\nThen in ```path_patterns``` you can use ```%%current_device%%``` parameter (with your device type as value)\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    path_patterns:\n        app_resource:\n            - %%app_path%%/themes/%%current_theme%%/%%current_device%%/%%template%%\n            - %%app_path%%/themes/fallback_theme/%%current_device%%/%%template%%\n            - %%app_path%%/views/%%current_device%%/%%template%%\n```\n\nOptionally ``autodetect_theme`` can also be set to a DIC service id that implements\nthe ``Liip\\ThemeBundle\\Helper\\DeviceDetectionInterface`` interface.\n\n### Get active theme information from cookie\n\nIf you want to select the active theme based on a cookie you can add:\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    cookie:\n        name: NameOfTheCookie\n        lifetime: 31536000 # 1 year in seconds\n        path: /\n        domain: ~\n        secure: false\n        http_only: false\n```\n\n### Disable controller based theme switching\n\nIf your application doesn't allow the user to switch theme, you can deactivate\nthe controller shipped with the bundle:\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    load_controllers: false\n```\n\n### Theme Cascading Order\n\nThe following order is applied when checking for templates that live in a bundle, for example `@BundleName/Resources/template.html.twig`\nwith theme name ``phone`` is located at:\n\n1. Override themes directory: `app/Resources/themes/phone/BundleName/template.html.twig`\n2. Override view directory: `app/Resources/BundleName/views/template.html.twig`\n3. Bundle theme directory: `src/BundleName/Resources/themes/phone/template.html.twig`\n4. Bundle view directory: `src/BundleName/Resources/views/template.html.twig`\n\nFor example, if you want to integrate some TwigBundle custom error pages regarding your theme\narchitecture, you will have to use this directory structure :\n`app/Resources/themes/phone/TwigBundle/Exception/error404.html.twig`\n\nThe following order is applied when checking for application-wide base templates, for example `::template.html.twig`\nwith theme name ``phone`` is located at:\n\n1. Override themes directory: `app/Resources/themes/phone/template.html.twig`\n2. Override view directory: `app/Resources/views/template.html.twig`\n\n#### Change Theme Cascading Order\n\nYou able change cascading order via configurations directives: `path_patterns.app_resource`, `path_patterns.bundle_resource`, `path_patterns.bundle_resource_dir`. For example:\n\n``` yaml\n# app/config/config.yml\nliip_theme:\n    path_patterns:\n        app_resource:\n            - %%app_path%%/themes/%%current_theme%%/%%template%%\n            - %%app_path%%/themes/fallback_theme/%%template%%\n            - %%app_path%%/views/%%template%%\n        bundle_resource:\n            - %%bundle_path%%/Resources/themes/%%current_theme%%_%%current_device%%/%%template%%\n            - %%bundle_path%%/Resources/themes/%%current_theme%%/%%template%%\n            - %%bundle_path%%/Resources/themes/fallback_theme/%%template%%\n        bundle_resource_dir:\n            - %%dir%%/themes/%%current_theme%%/%%bundle_name%%/%%template%%\n            - %%dir%%/themes/fallback_theme/%%bundle_name%%/%%template%%\n            - %%dir%%/%%bundle_name%%/%%override_path%%\n```\n\n##### Cascading Order Patterns Placeholders\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003ePlaceholder\u003c/th\u003e\n  \u003cth\u003eRepresentation\u003c/th\u003e\n  \u003cth\u003eExample\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%app_path%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003ePath where application resources are located\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eapp/Resources\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%bundle_path%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003ePath where bundle located, for example\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003esrc/Vendor/CoolBundle/VendorCoolBundle\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%bundle_name%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eName of the bundle\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eVendorCoolBundle\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%dir%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eDirectory, where resource should looking first\u003c/td\u003e\n  \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%current_theme%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eName of the current active theme\u003c/td\u003e\n  \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e%current_device%\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eName of the current device type\u003c/td\u003e\n    \u003ctd\u003edesktop, phone, tablet, plain\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%template%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eTemplate name\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eview.html.twig\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e%override_path%\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eLike template, but with views directory\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eviews/list.html.twig\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\n### Change Active Theme\n\nFor that matter have a look at the ThemeRequestListener.\n\nIf you are early in the request cycle and no template has been rendered you\ncan still change the theme without problems. For this the theme service\nexists at:\n\n``` php\n$activeTheme = $container-\u003eget('liip_theme.active_theme');\necho $activeTheme-\u003egetName();\n$activeTheme-\u003esetName(\"phone\");\n```\n\n### Theme Specific Controllers\n\nIn some situations, a different template is not enough and you need a different \ncontroller for a specific theme. We encountered this with A/B testing. Do not \nabuse this feature and check whether your use case is still to be considered a \ntheme.\n\nThis feature is not active by default as there is an additional request \nlistener involved. Enable it by setting `theme_specific_controllers` in your \nconfiguration:\n\n\n```yaml\n# app/config/config.yml\nliip_theme:\n    # ...\n    theme_specific_controllers: true\n```\n\nNow you can configure controllers per theme in your routing file:\n\n```yaml\nmy_route:\n    path: /x/y\n    defaults:\n        _controller: my_service:fooAction\n        theme_controllers:\n            a: my_other_service:fooAction\n            b: App:Other:foo\n```\n\nAs usual, you can use both the service notation or the namespace notation for\nthe controllers. Just specify the controller by theme under the key \n`theme_controllers`.\n\n### Assetic integration\n\nBecause of the way the LiipThemeBundle overrides the template locator service,\nassetic will only dump the assets of the active theme.\n\nIn order to dump the assets of all themes enable the ``assetic_integration``\noption:\n\n````yaml\n# app/config/config.yml\nliip_theme:\n    # ...\n    assetic_integration: true\n````\n\nThis will override the Twig formula loader and iterate over all of the themes,\nensuring that all of the assets are dumped.\n\nNote that this only works with AsseticBundle 2.1 or higher.\n\n### Override the Device Detection\n\nIt is possible to override the service used for the device detection. Make sure to either\nextend `DeviceDetection` or implement `DeviceDetectionInterface`:\n\n````yaml\n# app/config/config.yml\nservices:\n    my_devcice_detection:\n        class: SomeClass\n\nliip_theme:\n    # ...\n    device_detection: my_devcice_detection\n````\n\n## Migrate to SyliusThemeBundle\n\nThis will show you the stepts to switch from the [LiipThemeBundle](https://github.com/liip/LiipThemeBundle) to [SyliusThemeBundle](https://github.com/Sylius/SyliusThemeBundle).\n\n#### Remove the old theme bundle and install the SyliusThemeBundle:\n\n```bash\n# Remove old theme-bundle\ncomposer remove liip/theme-bundle --no-update\n\n# Install new theme-bundle\ncomposer require sylius/theme-bundle:\"^2.0\"\n```\n\n#### Remove old configuration\n\nThe old `liip_theme.yaml` configuration needs to be removed:\n\n```diff\n-liip_theme:\n-    themes: ['awesome']\n-    active_theme: 'awesome'\n```\n\nIn the next step you see how you configure the **awesome** theme using the SyliusThemeBundle.\n\n#### Configure the SyliusThemeBundle:\n\nIn order to use the bundle you have to add the following default configuration:\n\n```yaml\n# ./config/packages/sylius_theme.yaml\n\nsylius_theme:\n    sources:\n        filesystem: ~\n```\n\nBy default, the bundle seeks for the themes in the `%kernel.project_dir%/themes` directory and looks for a configuration\nfile named `composer.json`. This can be changed via the yaml configuration:\n\n```yaml\nsylius_theme:\n    sources:\n        filesystem:\n            filename: theme.json\n```\n\n#### Convert Theme Configuration\n\nIn the SyliusThemeBundle every theme must have its own configuration file in form of a `theme.json`.\nAdd a `theme.json` file and add the following minimal configuration:\n\n```diff\n{\n    \"name\": \"app/awesome\"\n}\n```\n\nGo to the [Theme Configuration Reference](https://github.com/Sylius/SyliusThemeBundle/blob/master/docs/theme_configuration_reference.md)\nfor the detailed documentation about the configuration options.\n\nMost likely you have to change the theme name. It is important, that the `name` matches the naming convention of composer (`vendor/name`).\nFurthermore the `theme.json` has to be moved into the directory for this specific theme. \n\nFor example: `%kernel.project_dir%/themes/awesome/theme.json`\n\n#### Update project structure\n\nYour templates have to be placed in a `templates` directory next to the `theme.json` file.\n\nFor example: `%kernel.project_dir%/themes/\u003ctheme-name\u003e/templates`\n\nThis results in the following project structure:\n\n```\nProjectName\n├── composer.json\n├── assets\n├── bin\n├── config\n├── templates\n├── themes\n│   ├── awesome\n│   │   ├── templates\n│   │   │   └── base.html.twig\n│   │   └── theme.json\n│   └── \u003ctheme-name-2\u003e\n│       ├── templates\n│       │   └── base.html.twig\n│       └── theme.json\n├── ...\n└── ...\n```\n\nAs you can see in the project structure, each theme must have their own `theme.json` configuration file next to the\ntemplates directory.\n\n#### Create ThemeRequestListener\n\nYou need to create a ThemeRequestListener to set the theme based on the current `$request` data:\n\n```php\nuse Sylius\\Bundle\\ThemeBundle\\Context\\SettableThemeContext;\nuse Sylius\\Bundle\\ThemeBundle\\Repository\\ThemeRepositoryInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\nfinal class ThemeRequestListener\n{\n    /** @var ThemeRepositoryInterface */\n    private $themeRepository;\n\n    /** @var SettableThemeContext */\n    private $themeContext;\n\n    public function __construct(ThemeRepositoryInterface $themeRepository, SettableThemeContext $themeContext)\n    {\n        $this-\u003ethemeRepository = $themeRepository;\n        $this-\u003ethemeContext = $themeContext;\n    }\n\n    public function onKernelRequest(GetResponseEvent $event): void\n    {\n        if (HttpKernelInterface::MASTER_REQUEST !== $event-\u003egetRequestType()) {\n            // don't do anything if it's not the master request\n            return;\n        }\n\n        $themeName = 'app/awesome';\n\n        // here you can set the $themeName based on $event-\u003egetRequest() object\n\n        $this-\u003ethemeContext-\u003esetTheme(\n            $this-\u003ethemeRepository-\u003efindOneByName($themeName)\n        );\n    }\n}\n```\n\nHave a look also at the [SyliusThemeBundle Documentation](https://github.com/Sylius/SyliusThemeBundle/tree/master/docs/index.md).\n\n## Contribution\n\nActive contribution and patches are very welcome. To keep things in shape we\nhave quite a bunch of unit tests. If you're submitting pull requests please\nmake sure that they are still passing and if you add functionality please\ntake a look at the coverage as well it should be pretty high :)\n\nFirst install dependencies:\n\n```bash\n   composer.phar install --dev\n```\n\nThis will give you proper results:\n\n``` bash\nphpunit --coverage-text\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliip%2Fliipthemebundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliip%2Fliipthemebundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliip%2Fliipthemebundle/lists"}