{"id":21068935,"url":"https://github.com/brandcom/cakephp-content-blocks","last_synced_at":"2025-03-14T02:23:43.088Z","repository":{"id":40263589,"uuid":"471367053","full_name":"brandcom/cakephp-content-blocks","owner":"brandcom","description":null,"archived":false,"fork":false,"pushed_at":"2022-11-18T15:21:48.000Z","size":653,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-21T04:04:54.610Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brandcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-18T12:53:35.000Z","updated_at":"2024-04-03T07:03:23.000Z","dependencies_parsed_at":"2023-01-22T11:15:58.640Z","dependency_job_id":null,"html_url":"https://github.com/brandcom/cakephp-content-blocks","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandcom%2Fcakephp-content-blocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandcom%2Fcakephp-content-blocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandcom%2Fcakephp-content-blocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandcom%2Fcakephp-content-blocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brandcom","download_url":"https://codeload.github.com/brandcom/cakephp-content-blocks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243510056,"owners_count":20302296,"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":[],"created_at":"2024-11-19T18:29:30.921Z","updated_at":"2025-03-14T02:23:43.030Z","avatar_url":"https://github.com/brandcom.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ContentBlocks plugin for CakePHP\n\n## Installation\n\nYou can install this plugin into your CakePHP application using [composer](https://getcomposer.org).\n\nThe recommended way to install composer packages is:\n\n```\ncomposer require brandcom/cakephp-content-blocks\n```\n\nLoad the plugin: \n\n```\nbin/cake plugin load ContentBlocks\n```\n\n... and run the migrations: \n\n```\nbin/cake migrations migrate --plugin ContentBlocks\n```\n\n## Getting Started\n\n### 1. Create Blocks\n\nThe plugin does not come with any blocks, so you will have to create them on your own. \n\nLet's create a simple TextContentBlock with a `title` and a `content` field. \n\n\u003e **Note:** Every ContentBlock must end with `*ContentBlock`\n\n1. In your database, create a table `text_content_blocks` with the fields `title` (Varchar 255) and `content` (Text). **Note:** You will also need an `id` field and a field `content_blocks_block_id` as `int(11), unsigned`.\n2. Then, run the `bin/cake bake model text_content_blocks` command. You won't need any templates or controllers.\n3. Edit the baked `TextContentBlock.php` file and make the class extend `ContentBlocks\\Model\\Entity\\Block` instead of `Entity`.\n\n4. Modify your `TextContentBlocksTable.php` so that your `TextContentBlocksTable` extends `ContentBlocks\\Model\\Entity\\BlocksTable`, and modify the class as follows:\n\nSet the relation: \n```\n$this-\u003ebelongsTo('Blocks', [\n    'foreignKey' =\u003e 'content_blocks_block_id',\n    'className' =\u003e 'ContentBlocks.Blocks',\n]);\n```\n\nFix the `buildRules()` method, set `table` to `Blocks`: \n```\n$rules-\u003eadd($rules-\u003eexistsIn(['content_blocks_block_id'], 'Blocks'));\n```\n\n\nYou will find more on customizing your Block below, but let's now add it to one of your pages. \n\n### 2. Admin interface\n\nTo add your TextContentBlock to an Entity, e.g., `Article`, add the `BlocksAdmin` cell to your edit template: \n\n```\n\u003c?= $this-\u003ecell(\"ContentBlocks.BlocksAdmin\", ['entityOrKey' =\u003e $article]) ?\u003e\n```\n\nThis will render a table representing the BlockArea for the respective entity. \n\n**New in version 0.3:** You can also create Areas for custom keys, e.g. on other places on your site or for index pages:\n\n```\n\u003c?= $this-\u003ecell(\"ContentBlocks.BlocksAdmin\", ['entityOrKey' =\u003e 'my_custom_key']) ?\u003e\n```\n\nAt the bottom of the table, there will be a button for each of your ContentBlocks. You should already find a button with the title `Text`. \n\nIf you click on the button, a new Block will be added to the Block Area. You can enter content and save.\n\n### 3. Create a template for your block\n\nContentBlock templates are elements. In your `Template/Element` folder, create the folder `content_blocks/` and the file `text.ctp`. \n\nThe template file name is always the lower_case_underscore version of your model name, omitting the content_block. \n\nSo the template for `MyCoolHeroHeaderContentBlock` will be in `/Template/Element/content_blocks/my_cool_hero_header.ctp`. \n\nYour `TextContentBlock` Entity will be available as the `$block` variable. \n\nNow you can create your template: \n\n```\n\u003c?php\n/**\n * @var \\App\\Model\\Entity\\TextContentBlock $block\n */\n?\u003e\n\u003csection class=\"my-12\"\u003e\n    \u003ch2\u003e\n        \u003c?= $block-\u003etitle ?\u003e\n    \u003c/h2\u003e\n    \u003cdiv class=\"content\"\u003e\n        \u003c?= $block-\u003econtent ?\u003e\n    \u003c/div\u003e\n\u003c/section\u003e\n```\n\n\u003e **Note:** You can change the rendering logic in your `TextContentBlock` Entity by overriding the `render()` method. \n\n### 4. Display the blocks\n\nTo render your block area for an entity, add this cell to your template:\n\n```\n\u003c?= $this-\u003ecell(\"ContentBlocks.BlocksArea\", ['entity' =\u003e $article]) ?\u003e\n```\n\n### 5. Modifying the Admin interface \n\nIf you want to change how fields are displayed, you can override the `getFields()` method in your `TextContentBlock` Entity.\n\nThe method should return an array of all editable fields with the field names as keys and an array as value which is passed to `FormHelper::control` as `$options`: \n\n```\npublic function getFields(): array\n{\n    return array_merge(\n        parent::getFields(),\n        [\n            'title' =\u003e [\n                'label' =\u003e __(\"Block Title\"),\n            ],\n            'style' =\u003e [\n                'label' =\u003e __(\"Choose a style for this block.\"),\n                'options' =\u003e [\n                    'default' =\u003e __(\"Default Style\"),\n                    'funky' =\u003e __(\"Other cool Style\"),\n                ],\n            ],\n        ]\n    );\n}\n```\n\nSpecial field options: \n* `beforeControl`: Will be rendered before the respective control.\n* `afterControl`: Will be rendered after the respective control. \n\nTo change the hidden fields, override `Block::getHiddenFields()`:\n\n```\npublic function getHiddenFields(): array\n{\n    return array_merge(\n        parent::getHiddenFields(),\n        [\n            'some_field',\n            'another_hidden_field',\n        ]\n    );\n}\n```\n\nE.g., `content_blocks_block_id` is hidden by default, and you may want to make it editable. \n\n\n### 6. Containing associated Models \n\nDefine a `beforeFind()` method in your `TextContenBlocksTable` \n\n```\npublic function beforeFind(Event $event, Query $query): Query\n{\n    return $query-\u003econtain([\n        'Images',\n    ]);\n}\n```\n\n### 7. Edit related models\n\nThe plugin supports an admin interface even for related models. \n\n#### HasMany relations\n\nSay you have a  `SliderContentBlock` with several slides. This means, you will have e.g. a `SliderBlockSlide` entity and \na `SliderBlockSlidesTable`. \n\n1. Let your Slide entity use the `ContentBlocks\\Model\\Entity\\Traits\\BelongsToBlockTrait`\n2. Contain the Slide as shown in **6. Containing associated Models** \n3. In your `SliderContentBlock`, override the `Block`'s method `getManagedModels()`. This should return an array of all related models which shall be editable in the admin form.\n\n```\npublic function getManagedModels(): array\n{\n    return [\n        \"SliderBlockSlides,\"\n    ];\n}\n```\n\n4. To customize the appearance in the admin form, you can override the methods from the `BelongsToBlockTrait`, e.g. to define a nicer title or control what fields are available for editing (similarly as in **5. Modifying the Admin interface**). \n\n### 8. Pass custom data to the block template\n\nBy default, the containing model of the block area is passed to the template as `$owner`, \nso, e.g., if you have an `Article` entity which has a `TextContentBlock`, your article entity will be accessible \nin the `text.ctp` as `$owner`. \n\nYou can override this - and add more view variables - by overriding the `getViewVariables()` method in your `*ContentBlocksTable`.\n\nIf you want to rename `$owner` and add more data, you can do that like so:  \n\n```\npublic function getViewVariables($entity): array\n{\n    $vars = parent::getViewVariables($entity);\n\n    return [\n        'article' =\u003e $vars['owner'],\n        'random' =\u003e \"This is just a string\",\n        'someOtherVariable' =\u003e $this-\u003egetSomeOtherVariable($entity),\n    ];\n}\n```\n\n`$entity`, the instance of your `*ContentBlock`, will be passed to the method.\n\n### 9. Allow or disallow the ContentBlock on specific Entities\n\nIf an Entity's model is listed in ContentBlock::getDisallowedEntities(), it will never be visible in the Block list. \n\n```\nprotected function getDisallowedEntities(): array\n{\n    return [\n        \"Articles\",\n        \"Jobs\",\n    ];\n}\n```\n\nYou can also define a list of allowed Entities: \n\n```\nprotected function getAllowedEntities(): array\n{\n    return [\n        \"BlogPosts\",\n    ];\n}\n```\n\n\u003e **Note:** If a model is listed in both, it will be disallowed.\n\n### 10. Block HTML-Anchors and (custom) preview-link\n\n**New in 0.2.0:** Every Block has a field for an HTML-Anchor. A link to the anchor is displayed below. \n\nTo override the default route, you can define a url on your `$owner` entity which holds the Area, e.g. `Articles`. \nThis can be useful, if your URL uses a `slug` or other parameters. The `$block` instance will be passed to the method:  \n\n```\npublic function getContentBlocksViewUrl(Block $block): array\n{\n    $anchor = $block-\u003ehtml_anchor ?: \"content-block-\" . $block-\u003eid;\n\n    return [\n        'prefix' =\u003e false,\n        'plugin' =\u003e false,\n        'controller' =\u003e 'Articles',\n        'action' =\u003e 'view',\n        $this-\u003eslug,\n        '#' =\u003e $anchor,\n    ];\n}\n```\n\n## Contribution\n\nYou can contribute to this project via pull requests or issues. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandcom%2Fcakephp-content-blocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrandcom%2Fcakephp-content-blocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandcom%2Fcakephp-content-blocks/lists"}