{"id":19250248,"url":"https://github.com/charcoalphp/view","last_synced_at":"2025-02-23T16:27:43.677Z","repository":{"id":37490977,"uuid":"505906951","full_name":"charcoalphp/view","owner":"charcoalphp","description":"[READ-ONLY] Charcoal Views (mustache, php, or more)","archived":false,"fork":false,"pushed_at":"2024-03-13T15:05:18.000Z","size":1839,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-06T14:17:52.271Z","etag":null,"topics":["charcoal","php","read-only-repository","viewengine"],"latest_commit_sha":null,"homepage":"https://github.com/charcoalphp/charcoal","language":"PHP","has_issues":false,"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/charcoalphp.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-06-21T15:46:03.000Z","updated_at":"2022-06-21T16:21:10.000Z","dependencies_parsed_at":"2024-01-13T04:49:47.158Z","dependency_job_id":"2538f1b8-8e58-477b-9581-c060e4d75ac1","html_url":"https://github.com/charcoalphp/view","commit_stats":{"total_commits":221,"total_committers":8,"mean_commits":27.625,"dds":0.330316742081448,"last_synced_commit":"8ad8aaf6f89a78d9489825750c08de5145151a46"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charcoalphp%2Fview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charcoalphp%2Fview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charcoalphp%2Fview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charcoalphp%2Fview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charcoalphp","download_url":"https://codeload.github.com/charcoalphp/view/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240342739,"owners_count":19786567,"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":["charcoal","php","read-only-repository","viewengine"],"created_at":"2024-11-09T18:16:37.101Z","updated_at":"2025-02-23T16:27:43.658Z","avatar_url":"https://github.com/charcoalphp.png","language":"PHP","readme":"Charcoal View\n=============\n\nThe View package provides an integration with [Mustache] and [Twig] for templating.\n\n## Installation\n\n```shell\ncomposer require charcoal/view\n```\n\nFor Charcoal projects, the service provider can be registered from your configuration file:\n\n```json\n{\n    \"service_providers\": {\n        \"charcoal/view/service-provider/view\": {}\n    }\n}\n```\n\n## Usage\n\nIt is a thin layer on top of various _rendering engines_, such as **mustache** or **twig** that can be used either as a _View_ component with any frameworks, as PSR-7 renderer for such frameworks (such as Slim) \n\nA `View` can be used to render any template (which can be loaded from the engine) with any object (or array, for twig) as context.\n\n```php\nuse Charcoal\\View\\Mustache\\MustacheLoader;\nuse Charcoal\\View\\Mustache\\MustacheEngine;\nuse Charcoal\\View\\GenericView;\n\n$loader = new MustacheLoader([\n    'base_path' =\u003e __DIR__,\n    'paths'     =\u003e [\n        'templates',\n        'views',\n    ],\n]);\n\n$engine = new MustacheEngine([\n    'loader' =\u003e $loader,\n]);\n\n$view = new GenericView([\n    'engine' =\u003e $engine,\n]);\n\necho $view-\u003erender('foo/bar/template', $context);\n\n// A template string can also be used directly, with `renderTemplate()`\n$str = 'My name is {{what}}';\necho $view-\u003erenderTemplate($str, $context);\n```\n\n### Basic Usage, with service provider\n\nAll this bootstrapping code can be avoided by using the `ViewServiceProvider`. This provider expects a `config` object\n\n```php\nuse Pimple\\Container;\nuse Charcoal\\View\\ViewServiceProvider;\n\n$container = new Container([\n    'base_path' =\u003e __DIR__,\n    'view'      =\u003e [\n        'default_engine' =\u003e 'mustache',\n        'paths'          =\u003e [\n            'views',\n            'templates',\n        ],\n    ],\n]);\n$container-\u003eregister(new ViewServiceProvider());\n\necho $container['view']-\u003erender('foo/bar/template', $context);\n```\n\n\u003e 👉 The default view engine, used in those examples, would be _mustache_.\n\n### Using the Renderer, with Slim\n\nA view can also be implicitely used as a rendering service. Using the provided `view/renderer`, with a PSR7 framework (in this example, Slim 3):\n\n```php\nuse Charcoal\\View\\ViewServiceProvider;\nuse Slim\\App;\n\n$app = new App();\n$container = $app-\u003egetContainer();\n$container-\u003eregister(new ViewServiceProvider());\n\n$app-\u003eget('/hello/{name}', function ($request, $response, $args) {\n    // This will render the \"hello\" template\n    return $this-\u003erenderer-\u003erender($response, 'hello', $args);\n});\n\n$app-\u003erun();\n```\n\n\u003e Just like the view, it is possible to simply register all dependencies on a Pimple container (with the `ViewServiceProvider`) to avoid all this bootstrapping code. The renderer is available as `$container['view/renderer']`.\n\n## Module components\n\nThe basic components in the View package are:\n\n* [**View**](#views), which provide the basic interface to all components.\n* [**Engine**](#view-engines), to actually render the templates.\n* [**Loader**](#loader), to load _template files_.\n* [**Viewable**](#viewable-interface-and-trait), which allow any object to be rendered with a _View_.\n* **Renderer**, an extra helper to use a view to render into PSR-7 request/response objects.\n\n### Views\n\nThe `Charcoal\\View\\ViewInterface` defines all that is needed to render templates via a view engine:\n\n* `render($templateIdent = null, $context = null)`\n* `renderTemplate($templateString, $context = null)`\n\nThe abstract class `Charcoal\\View\\AbstractView` fully implements the `ViewInterface` and adds the methods:\n\n#### Generic view\n\nAs convenience, the `\\Charcoal\\View\\GenericView` class implements the full interface by extending the `AbstractView` base class.\n\n### View Engines\n\nCharcoal _views_ support different templating Engines_, which are responsible for loading the appropriate template (through a _loader_) and render a template with a given context according to its internal rules. Every view engines should implement `\\Charcoal\\View\\EngineInterface`.\n\nThere are 3 engines available by default:\n\n* `mustache` (**default**)\n* `php`\n* `twig`\n\n#### Mustache Helpers\n\nMustache can be extended with the help of `helpers`. Those helpers can be set by extending `view/mustache/helpers` in the container:\n\n```php\n$container-\u003eextend('view/mustache/helpers', function(array $helpers, Container $container) {\n    return array_merge($helpers, [\n        'my_extended_method' =\u003e function($text, LambdaHelper $lambda) {\n            if (isset($helper)) {\n                $text = $helper-\u003erender($text);\n            }\n            return customMethod($text);\n        },\n    ]);\n});\n```\n\n**Provided helpers:**\n\n* **Assets** helpers:\n  * `purgeJs`\n  * `addJs`\n  * `js`\n  * `addJsRequirement`\n  * `jsRequirements`\n  * `addCss`\n  * `purgeCss`\n  * `css`\n  * `addCssRequirement`\n  * `cssRequirements`\n  * `purgeAssets`\n* **Translator** helpers:\n  * `_t` Translate a string with `{{#_t}}String to translate{{/_t}}`\n* **Markdown** helpers:\n  * `markdown` Parse markdown to HTML with `{{#markdown}}# this is a H1{{/markdown}}`\n \n#### Twig Helpers\n\nTwig can be extended with the help of [TwigExtension](https://twig.symfony.com/doc/3.x/advanced.html#creating-an-extension). Those helpers can be set by extending `view/twig/helpers` in the container:\n\n```php\n$container['my/twig/helper'] = function (Container $container): MyTwigHelper {\n    return new MyTwigHelper();\n};\n\n$container-\u003eextend('view/twig/helpers', function (array $helpers, Container $container): array {\n    return array_merge(\n        $helpers,\n        $container['my/twig/helper']-\u003etoArray(),\n    );\n});\n```\n\n**Provided helpers:**\n\n* **Debug** helpers\n  * `debug` function `{{ debug() }}`\n  * `isDebug` function alias of `debug`\n* **Translator** helpers:\n  * `trans` filter a string with `{{ \"String to translate\"|trans }}`\n  * `transChoice` filter:\n    ```\n        {{ '{0}First: %test%|{1}Second: %test%'|transChoice(0, {'%test%': 'this is a test'}) }}\n        {# First: this is a test #}\n        {{ '{0}First: %test%|{1}Second: %test%'|transChoice(1, {'%test%': 'this is a test'}) }}\n        {# Second: this is a test #}\n    ```\n* **Url** helpers: \n  * `baseUrl` function `{{ baseUrl() }}`\n  * `siteUrl` function alias of `baseUrl`\n  * `withBaseUrl` function `{{ withBaseUrl('/example/path') }}`\n\n### Loaders\n\nA `Loader` service is attached to every engine. Its function is to load a given template content\n\n#### Templates\n\nTemplates are simply files, stored on the filesystem, containing the main view (typically, HTML code + templating tags, but can be kind of text data).\n\n* For the *mustache* engine, they are `.mustache` files.\n* For the *php* engine, they are `.php` files.\n* For the *twig* engine, they are `.twig` files.\n\nTemplates are loaded with template _loaders_. Loaders implement the `Charcoal\\View\\LoaderInterface` and simply tries to match an identifier (passed as argument to the `load()` method) to a file on the filesystem.\n\nCalling `$view-\u003erender($templateIdent, $context)` will automatically use the engine's `Loader` object to find the template `$templateIdent`.\n\nOtherwise, calling `$view-\u003erenderTemplate($templateString, $context)` expects an already-loaded template string as parameter.\n\n### Viewable Interface and Trait\n\nAny objects can be made renderable (viewable) by implementing the `Charcoal\\View\\ViewableInterface` by using the `Charcoal\\View\\ViewableTrait`.\n\nThe interface adds the following methods to their implementing objects:\n\n* `setTemplateIdent($ident)`\n* `templateIdent()`\n* `setView($view)`\n* `view()`\n* `render($templateIdent = null)`\n* `renderTemplate($templateString)`\n\n#### Examples\n\nGiven the following classes:\n\n```php\nuse \\Charcoal\\View\\ViewableInterface;\nuse \\Charcoal\\View\\ViewableTrait;\n\nclass MyObject implements ViewableInterface\n{\n    use ViewableTrait;\n\n    public function world()\n    {\n        return 'world!';\n    }\n}\n```\n\nThe following code:\n\n```php\n$obj = new MyObject();\n$obj-\u003erenderTemplate('Hello {{world}}');\n```\n\nwould output: `\"Hello world!\"`\n\n### View Service Provider\n\nAs seen in the various examples above, it is recommended to use the `ViewServiceProvider` to set up the various dependencies, according to a `config`, on a `Pimple` container.\n\nThe Service Provider adds the following service to a container:\n\n* `view` The base view instance.\n* `view/renderer` A PSR-7 view renderer.\n* `view/parsedown` A parsedown service, to render markdown into HTML.\n\nOther services / options are:\n\n* `view/config` View configuration options.\n* `view/engine` Currently used view engine.\n* `view/loader` Currently used template loader.\n\nThe `ViewServiceProvider` expects the following services / keys to be set on the container:\n\n* `config` Application configuration. Should contain a \"view\" key to build the _ViewConfig_ obejct.\n\n#### The View Config\n\nMost service options can be set dynamically from a configuration object (available in `$container['view/config']`).\n\n**Example for Mustache:**\n\n```json\n{\n    \"base_path\":\"/\",\n    \"view\": {\n        \"default_engine\":\"mustache\",\n        \"paths\":[\n            \"templates\",\n            \"views\"\n        ]\n    }\n}\n```\n\n**Example for Twig:**\n\n```json\n{\n    \"view\": {\n        \"default_engine\": \"twig\",\n        \"use_cache\": false,\n        \"strict_variables\": true,\n        \"paths\": [\n            \"templates\",\n            \"views\"\n        ]\n    }\n}\n```\n\n## Resources\n\n* [Contributing](https://github.com/charcoalphp/.github/blob/main/CONTRIBUTING.md)\n* [Report issues](https://github.com/charcoalphp/charcoal/issues) and\n  [send pull requests](https://github.com/charcoalphp/charcoal/pulls)\n  in the [main Charcoal repository](https://github.com/charcoalphp/charcoal)\n\n[Mustache]: https://github.com/bobthecow/mustache.php\n[Twig]:     https://github.com/twigphp/Twig\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharcoalphp%2Fview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharcoalphp%2Fview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharcoalphp%2Fview/lists"}