{"id":13669926,"url":"https://github.com/websemantics/builder-extension","last_synced_at":"2025-04-09T23:30:47.670Z","repository":{"id":30196070,"uuid":"33746900","full_name":"websemantics/builder-extension","owner":"websemantics","description":"Scaffold your PyroCMS apps in style for a more pleasurable and productive coding experience.","archived":false,"fork":false,"pushed_at":"2018-09-12T06:44:53.000Z","size":434,"stargazers_count":12,"open_issues_count":9,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T13:21:22.327Z","etag":null,"topics":["pyrocms","pyrocms-extenstions","pyrocms3"],"latest_commit_sha":null,"homepage":"https://github.com/pyrocms-templates","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/websemantics.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-10T19:31:49.000Z","updated_at":"2023-07-10T00:38:55.000Z","dependencies_parsed_at":"2022-08-24T13:10:15.591Z","dependency_job_id":null,"html_url":"https://github.com/websemantics/builder-extension","commit_stats":null,"previous_names":["websemantics/entity_builder-extension"],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/websemantics%2Fbuilder-extension","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/websemantics%2Fbuilder-extension/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/websemantics%2Fbuilder-extension/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/websemantics%2Fbuilder-extension/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/websemantics","download_url":"https://codeload.github.com/websemantics/builder-extension/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248129532,"owners_count":21052589,"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":["pyrocms","pyrocms-extenstions","pyrocms3"],"created_at":"2024-08-02T09:00:25.612Z","updated_at":"2025-04-09T23:30:47.236Z","avatar_url":"https://github.com/websemantics.png","language":"PHP","funding_links":[],"categories":["Extensions"],"sub_categories":[],"readme":"```\n\n                                                 /'\\\n                                                /   \\\n                                               /     \\\n                             _                /   ..' \\_                      /\\/'\\\n                            / \\              / './       \\                   /     \\\n                          _/   \\            /             \\        _        / oO    \\\n                /'\\      /  '._'\\          /               \\      / \\      /      /''\\\n               /   \\    /        \\        /      /          \\    /   \\    / \\_ ..'    \\\n              /     \\  /          \\__    /      /            \\  /     \\__/             \\\n                     \\/              \\  /      /              \\/__     \\                \\\n                      \\               \\/    __/                   \\     \\                \\\n                       \\              /                            \\     \\\n                                              ))))                        \\__\n                 _________ _______     __ooO_(O o)_Ooo____\n                |          \\      \\   /     | (_)         \\\\===========\\===========\\\n                |     __    \\      \\ /      |     __      |            |           |\n                |    |__)    \\      V      /|    |__)     |            |           |\n                |            |\\           / |            \u003c            ┌┴┐         ┌┴┐\n                |        ___/  |         |  |             \\          _ \\ \\       /  |\n                |       |      |         |  |      |\\      \\        | \\_| |     |    \\_\n                |       |      |         |  |      | \\      \\        \\___/  __  \\      `-_\n                |_______|      |_________|  |______|  |______|             /   \\  ''-.    \\\n                 ____   __ __  ____  _     ___      ___  ____             /    /      \\    \\\n                |    \\ |  |  ||    || |   |   \\    /  _||    \\            |   |        |   |\n                | ()  )|  |  | |  | | |\\\\\\\\    \\  /  |_ | ()  )           \\    \\      /    /\n                |     ||  |  | |  | |  ( oo) () ||    _||    /             \\    `-..-'    /\n                | ()  ||  :  | |  | |   (_)     ||   |_ |    \\       - --   '-_        _-'\n                |_____| \\__,_||____||____||_____||_____||__|\\_|                `------'\n                Addons scaffolder for maximum coding pleasure            - -- --------- -- -\n\n```\n\u003e This PyroCMS 3 extension once installed becomes your coding companion to scaffold Pyro modules, themes, extensions and [stream entities](#stream-entities).\n\n## Motivation\n\nHere are some of the thoughts and reasons behind building the builder extension,\n\nFrom the prospective of a developer, Pyro 3 reduces complexity and introduces simplicity and structure into building large scale web applications with its [modular design](https://en.wikipedia.org/wiki/Modular_design), Modules, Extension, etc and data structure abstraction ([ATD](https://en.wikipedia.org/wiki/Abstract_data_type)), realized in the [Stream Platform](https://github.com/anomalylabs/streams-platform),\n\nHowever, with structure comes repetition and the need to use boilerplate code combined with predefined set of steps to integrate that with your application. Usually this is all covered in the documentation, but who has time for that?\n\nThis extension tries to remove some of that tedious work so that the developer can focus on writing business logic of the application. To achieve that, the builder offers a number of commands and provide scaffolders for the different aspects of building a Pyro application,\n\nFor examples, once installed, the extension will scaffold a software structure called [Entity](#stream-entities) for every stream migration generated with the `make:stream` command. The code generated includes `Models`, `Repositories`, `Table Builders`, `Form Builders`, `Admin Controllers`, `Seeders` to name a few. And with the help of a [PHP parser](https://github.com/nikic/PHP-Parser), it will configure the module classes with routes, bindings, language file entries and even seeding and even helper functions.\n\n## Install\n\nIn your project folder, require the extension with `composer` and then install as follows,\n\n```bash\ncomposer require websemantics/builder-extension\nphp artisan extension:install websemantics.extension.builder\n```\n\n## Getting Started\n\nThe first command to use when developing a Pyro application with the builder extension is `make:addon`. The default `make:addon` command has been extended to enable [*template-based*](#make-template) code scaffolding.\n\n## Make Addon\n\nUse the `make:addon` command as per usual, [documentation](https://www.pyrocms.com/documentation) to create modules, themes and other addon types. However, there are two new concepts that this extension introduces,\n\n1- A [default template](#environment-variables) is prescribed for each addon type (if [available](#list-templates)) that the builder downloads and uses to generate code.\n\n2- Each template come with a schema (a list of variable, for example, `vendor`, `slug` etc) that the builder uses to scaffold code. These variables have default values but the user will be ask to change their values interactively unless the `--defaults` option is used to [skip](#make-addon) the process.\n\n#### Make Module\n\n```bash\nphp artisan make:addon vendor.module.name\n```\n\nThe previous command creates a module based on the [default module](https://github.com/pyrocms-templates/default-module) template. The downloaded module template will be cached  at `storage/streams/default/builder/default-module`.\n\n**NOTE**: A fields migration file will not be generated as per Pyro 3 default `make:addon` command behaviour. The builder extension generates a separate fields migration file for each [stream migration](#make-stream) instead.\n\n#### Make Theme\n\nThere are two templates to generate a theme addon, an [*admin*](https://github.com/pyrocms-templates/pyrocms-theme) and a [*front-end*](https://github.com/pyrocms-templates/starter-theme).\n\n```bash\nphp artisan make:addon vendor.theme.name --force --admin\n```\n\nThe `--force` option forces the extension to download a fresh copy of the template and `--admin` to create an *admin* theme. Omit `--admin` option to create a *front-end* theme.\n\n#### Make Addon\n\nThe previous uses of `make:addon` make assumptions about the template to use when creating the addon ([default module](https://github.com/pyrocms-templates/default-module), [pyrocms-theme](https://github.com/pyrocms-templates/pyrocms-theme) etc). This behaviour can be changed by providing an optional template name, `default-module` as follows,\n\n```bash\nphp artisan make:addon websemantics.module.name default-module --defaults\n```\n\nThe `defaults` options disables the user interactive mode and forces the template defaults. This command also supports `--shared` and `--migrate` options.\n\n#### Make Template\n\nA template is like a recipe that the extension uses to scaffold code for an addon type, or any software package for that matter,\n\n```bash\nphp artisan make:addon websemantics.module.name --template\n```\n\nThe previous command will create a template for the specified addon type, `defaults` and uses `vendor` and `slug` provided as default values for the template schema. More details about templates and how to use them locally can be found at [template-template documentation](https://github.com/pyrocms-templates/template-template).\n\n## List Templates\n\nThis command will list all available addon templates from the [registry](#the-registry),\n\n```bash\nphp artisan builder:list\n```\n\nResult,\n\n```\n ____   __ __  ____  _     ___      ___  ____\n|    \\ |  |  ||    || |   |   \\    /  _||    \\\n| ()  )|  |  | |  | | |\\\\\\\\    \\  /  |_ | ()  )\n|     ||  |  | |  | |  ( oo) () ||    _||    /\n| ()  ||  :  | |  | |   (_)     ||   |_ |    \\\n|_____| \\__,_||____||____||_____||_____||__|\\_|\nAddons scaffolder for maximum coding pleasure\n\nBuilder Commands:\n- make:addon Create an addon from a template if avilable\n- builder:list List available templates from the registry\n- builder:clear Clear cache and locally stored templates\n\nRetrieving a list of available templates\n+-------------------+-----------------------------------------------------------------------+---+\n| Name              | Description                                                           | ★ |\n+-------------------+-----------------------------------------------------------------------+---+\n| default-module    | The default module template for Pyro Builder                          | 2 |\n| default-skin      | The default skin template for PyroCMS Plus Theme                      | 0 |\n| pyrocms-theme     | A customizable release of the official PyroCMS admin theme            | 2 |\n| starter-theme     | A customizable release of PyroCMS started theme                       | 4 |\n| template-template | The default Pyro Builder template for building Pyro Builder templates | 3 |\n+-------------------+-----------------------------------------------------------------------+---+\n```\n\nNotice how each template has one star only! :/ Well, you can change that by liking these repos [here](https://github.com/pyrocms-templates) :)\n\n## Clear Cache\n\nTo clear the builder cache and delete all locally downloaded templates run the following command,\n\n```bash\nphp artisan builder:clear\n```\n\n## Make Stream\n\nThe builder introduces new abilities to `make:stream` command, for example, to specify stream properties and fields,\n\nUsing the example provided in [Auto-pyro](https://github.com/websemantics/auto-pyro) to create a [todo module](https://github.com/websemantics/auto-pyro/blob/1.0.0/local.properties#L97), the following will create a `Task` stream and all of it's assignments,\n\n```bash\nphp make:stream 'task:tc(name),name,description:t(anomaly.field_type.textarea),completed:t(anomaly.field_type.boolean)' websemantics.module.todo\n```\n\nInstead of specifying the stream `slug` only, `make:stream` command now accepts a comma-separated list of fields following the stream slug and properties.\n\nThe following is a complete list of options available to use with streams and field. Option values - if applicable - are provided between parentheses (as in the example above),\n\n| Property        | Shorthand           | Inheritable |\n| ------------- |:-------------:|:-------------:|\n| title_column | `tc` | :white_medium_square: |\n| type | `t` | :white_medium_square: |\n| required | `r` | :white_medium_square: |\n| unique | `u` | :white_medium_square: |\n| searchable | `s` | :white_medium_square: |\n| locked | `l` | :white_medium_square: |\n| translatable | `trans` | :white_check_mark: |\n| trashable | `trash` | :white_check_mark: |\n| sortable | `sor` | :white_check_mark: |\n\nThe `Inheritable` column indicates the properties a stream would inherit if one of its fields has it set to true.  For example,\n\n```bash\n# First, generate the module\nphp artisan make:addon vendor.module.name\n\n# Then generate the stream migration files\nphp artisan make:stream 'comment:title_column(name),name:trans' vendor.module.name\n\n# This can also be expressed as\nphp artisan make:stream 'comment:title_column(name),name:translatable(true)' vendor.module.name\n\n# Or as,\nphp artisan make:stream 'comment:title_column(name):translatable(true),name:type(anomaly.field_type.text):translatable(true)' vendor.module.name\n```\n\nThe previous will generate a stream migration as follows,\n\n```php\n  protected $stream = [\n\t\t\t'slug'                        =\u003e 'comment',\n\t\t\t'title_column'                =\u003e 'name',\n\t\t\t'translatable'                =\u003e true\n\t];\n\n  protected $assignments = [\n\t\t\t'name'                          =\u003e [\n\t\t\t\t\t'translatable'              =\u003e true\n\t\t\t]\n\t];\n```\n\nIf the `type` property of a field is not set, the builder extension will assume `anomaly.field_type.text` as default.\n\n#### Environment Variables\n\nAll environment variables used by the extension are listed here,\n\n|  Variable        | Description     | Default |\n| ------------- |-------------|-------------|\n| *BUILDER_REGISTRY* | The default Builder Extension registry | `pyrocms-templates` |\n| *BUILDER_DEFAULT_TEMPLATE* | Template of templates to create an addon template | `template-template` |\n| *BUILDER_DEFAULT_MODULE* | Default template for modules | `default-module` |\n| *BUILDER_DEFAULT_ADMIN* | Default template for admin themes | `pyrocms-theme` |\n| *BUILDER_DEFAULT_FRONT* | Default template for front-end themes | `starter-theme` |\n| *BUILDER_TTL* | Time used to cache an API call | `60` minutes |\n| *BUILDER_PATH* | Path to the local storage to cache templates | `builder` |\n| *BUILDER_ARCHIVE_URL* | Url to the compressed file of the template repo| `url-template` |\n| *BUILDER_TMP* | Temporary folder to uncompress zip files | `folder` |\n| *MIGRATION_PADDING* | Padding between arrays `(key,value)`s in migration file | `30` chars |\n\nConfiguration file can be found at, `./resources/config/config.php`. Overridden in project `.env` file to change the default behaviour.\n\n## Stream Entities\n\nIn addition to scaffolding addons from builder templates, the builder offers generating stream entities from migrations. An Entity is a representation of an [Object Type](https://en.wikipedia.org/wiki/Object_type_(object-oriented_programming)) which may correspond with a Stream. For example, a **Person**, a **Company** or an **Animal** can all be represented by Streams and Entities.\n\nThe code generated for an entity includes an `Entity Model` and `Repository`, `Plugin`, `Seeder`, `Contracts`, `Table Builder` and `Form Builder`.\n\nPlease read the following section for a better understanding of this process.\n\n## Building a Blog\n\nThe source code of this example is available [here](https://github.com/websemantics/blog). The idea is to build a module with the least amount of effort and experience how the builder extension does its work,\n\n* Create and install a new PyroCMS project and name it `blogger`,\n\n```bash\n# first, create a fresh pyro project and change folder,\ncomposer create-project pyrocms/pyrocms --prefer-dist blogger\ncd blogger\n\n# install from the command line,\nphp artisan install\n```\n\n* Install the builder extension,\n\n```bash\ncomposer require websemantics/builder-extension\nphp artisan extension:install websemantics.extension.builder\n```\n\n* Create a new module, `blog`\n\n```bash\nphp artisan make:addon websemantics.module.blog\n```\n\n* Create `posts` stream and its fields,\n\n```bash\nphp artisan make:stream 'posts:tc(title),title:r:u,content:r' websemantics.module.blog\n```\n\nThe result,\n\n```php\n    protected $stream = [\n        'slug'         =\u003e 'posts',\n        'title_column' =\u003e 'title'\n    ];\n\n    protected $assignments = [\n        'title'        =\u003e [\n            'required' =\u003e true,\n            'unique'   =\u003e true\n        ],\n        'content'     =\u003e [\n            'required' =\u003e true,\n        ]\n    ];\n```\n\nThis will also generate a seeder template for this entity (see below),\n\n* Add seeder data to, `blog/addons/default/websemantics/blog-module/resources/seeders/post.php` (singular file name)\n\n```php\n  ['title' =\u003e 'Laravel', 'content' =\u003e 'PHP framework'],\n  ['title' =\u003e 'PyroCMS', 'content' =\u003e 'PHP CMS']\n```\n\nThe content must be a list of entry values without `\u003c?php`. This will be added to the Entity Seeder class when the code is (re)generated. This process will be enhanced in the near future with better code parsing.\n\n* Apply the changes by install/reinstall the module,\n\n```bash\nphp artisan module:reinstall websemantics.module.blog\n```\n\nCheck the admin panel to see the new Module in action, url: `admin/blog/posts`.\n\n## The Registry\n\nThe idea is to have a collection of reusable Pyro 3 addon templates that can be scaffolded from the command line, similar to what [vue-cli](https://github.com/vuejs/vue-cli) offers.\n\nFor a full list of what's available through the Builder extension, check the registry at, [PyroCMS Templates](https://github.com/pyrocms-templates) or use [`builder:list`](#list-templates) artisan command.\n\n## Development\n\nOnce the addon code have been generated and entity files per stream have been created and working correctly with Pyro, you might want to modify and develop the classes individually adding custom code,\n\nThe extension provides a configuration options to make your work easy, for example to list the files that you don't want to overwrite accidentally when re-installing a module to regenerating the entity code,\n\nAnother example, if you have edited the `blog-module/src/Blog/Post/PostModel.php`, make sure to list that in the builder config file, `blog-module/resources/config/builder.php` so that the extension will avoid overwriting these files if they exist.\n\nHere's an example,\n\n```\n  'avoid_overwrite' =\u003e [\n    'Model.php',\n    'Repository.php',\n    'TableColumns.php'\n  ],\n```\n\nNotice how only the last part of the file name (omitted the entity name) is used so that this can be applied globally to all generated entities of the same type,\n\n## Configuration\n\nThe Builder extension offers many configuration options to fine-tune and enhance your development experience which can be found at `blog-module/resources/config/builder.php`.\n\n* Add a list of namespaces supported,\n\n```php\n  'namespaces' =\u003e [\n    'blog' =\u003e [],\n    'discussion' =\u003e []\n  ]\n```\n\nThis indicates to the builder extension the stream `namespaces` that your module supports. Add namespaces to this list as appropriate.\n\n* Group entities code under a namespace folder,\n\nWhen code is generated for an entity, the builder extension saves it under `src/{namespace}` by default. This is useful when your module handles streams from different namespaces,\n\nTo change this behaviour and store under the module `src/` folder directly, set the `group` option to `false`,\n\n```\n  'group' =\u003e true,\n```\n\n* To seed after a successful install, set the `seed` option in `builder.php`,\n\n```\n  'seed' =\u003e true\n```\n\nTurn on and off with `true` / `false` values as needed.\n\n* To generate fields and streams permissions set `permissions` to true,\n\n```\n  'permissions' =\u003e true\n```\n\n* To generate sitemap, set the stream_slug for the module main stream, for example `pages` stream,\n\n```\n\t'sitemap' =\u003e [ 'stream_slug' =\u003e 'pages',\n                 'url_method' =\u003e '-\u003egetPath()',\n                 'entries_method' =\u003e '-\u003eaccessible()-\u003evisible()',\n                 'priority' =\u003e 0.5,\n                 'frequency' =\u003e 'monthly',\n                 'images' =\u003e '[]',\n                 'title' =\u003e 'null'\n               ],\n```\n\nThe `url_method` is used to retrieve the resource path, and `entries_method` should return a filtered collection of stream entries.\n\n* Specify your project docblock to be included with the generated classes,\n\n```\n'docblock' =\u003e\n' * @link      http://yourcompany.com\n * @author    name, \u003cname@email.com\u003e'\n```\n\nMore settings are detailed in the [builder.php](https://github.com/websemantics/builder-extension/blob/master/resources/assets/module/template/resources/config/builder.php) file.\n\n## Inner Working\n\nOnce installed, this extension listens mainly to three event types, *StreamWasCreated*, *AssignmentWasCreated* and *ModuleWasInstalled*.\n\nTo enable this extension for your current module, create a config file at `resources/config/builder.php` and list the namespaces you would like the extension to generate code for. You can listen/generate code to multiple namespaces.\n\n```php\n    'namespaces' =\u003e ['blogger', 'navigation', 'etc']\n```\n\nHere's an example of the [builder config file](https://github.com/websemantics/example-module/blob/master/resources/config/builder.php) taken from [Boxed](http://websemantics.github.io/boxed) example module github repo.\n\nOnce that's done, create your streams migration files as usual. The extension will kick in when it receives the events listed above,\n\n* For *StreamWasCreated* event, the extension will generate an entity folder for the stream from the template stored at `builder-extension/resources/assets/entity/code`. The folder map of the entity is as follows:\n\n```\nBlogEntity\n  |\n  +-- Contract\n  |      |\n  |      +--- BlogInterface.php\n  |      |\n  |      +--- BlogRepositoryInterface.php\n  |\n  |\n  +-- Form\n  |    |\n  |    +--- BlogFormBuilder.php\n  |\n  |\n  +-- Table\n  |     |\n  |     +--- BlogTableBuilder.php\n  |     |\n  |     +--- BlogTableColumns.php\n  |\n  |\n  +---- BlogModule.php\n  |\n  +---- BlogRepository.php\n  |\n  +---- BlogSeeder.php\n  |\n  +---- BlogPlugin.php\n```\n\nBy default, this folder structure would be generated in a subfolder at `src`. The name of the subfolder is the *namespace* of the created stream as explained above.\n\nThe extension will then generate a controller per entity at `blog-module/src/Http/Controller/Admin/BlogController.php` and modify `Module`, `ServiceProvider`, `Seeder` classes and language files to setup the entity to work correctly with the module.\n\n* For *AssignmentWasCreated* event, the extension will modify two files, `BlogTableColumns.php` and `BlogFormBuilder.php` and add a `field` slug per stream assignment.\n\n* For *ModuleWasInstalled* event, this will add `routes` and `sections` to the module and service provider. It will also seed the module if the builder config file was set accordingly.\n\n## Screencasts\n\nTo generate screen recordings, follow these steps,\n\n- Install [Asciinema](https://asciinema.org/) and [Asciinema 2 Gif](https://github.com/tav/asciinema2gif)\n\n```\nbrew install asciinema\nbrew install asciinema2gif\n```\n\nRecord a screencast and convert it to a gif image,\n\n```\nasciinema rec -y -t \"title\"\nasciinema2gif --size small --speed 3 https://asciinema.org/api/asciicasts/{{id}}\n```\n\nThe `asciinema` command will generate a url to the recording, for example,  `https://asciinema.org/a/e32g9nqayq1dqb9txd063ez8m`. Replace the `{{id}}` in the url provided for `asciinema2gif` with the one unique id from `asciinema` url, `e32g9nqayq1dqb9txd063ez8m`. Read the documentations for more details regarding [valid url formats](https://github.com/tav/asciinema2gif#url-format).\n\nCopy the generated file `asciicast.gif` from the current directory to the desired location.\n\n## Support\n\nNeed help or have a question? post a questions at [StackOverflow](https://stackoverflow.com/questions/tagged/builder-extension)\n\n*Please don't use the issue trackers for support/questions.*\n\n## Contribution\n\nWell finally, we are more than happy to accept external contributions to the project in the form of feedback, bug reports and even better - pull requests :)\n\n## Resources\n\n- [Auto Pyro](https://github.com/websemantics/auto-pyro), a PyroCMS deploy tool for faster development experience.\n- [Template Template](https://github.com/pyrocms-templates/template-template), The default Pyro Builder template for building Pyro Builder templates.\n- [Registry](https://github.com/pyrocms-templates),a list of all Pyro Builder available template.\n- [Awesome PyroCMS](https://github.com/websemantics/awesome-pyrocms), a curated list of PyroCMS addons and resources.\n- [PyroCMS Cheatsheet](http://websemantics.github.io/pyrocms-cheatsheet), A list of commands and features for PyroCMS 3.\n- [PyroCMS](https://github.com/pyrocms/pyrocms), an MVC PHP Content Management System built to be easy to use, theme and develop with. It is used by individuals and organizations of all sizes around the world.\n\n## License\n\n[MIT license](http://opensource.org/licenses/mit-license.php)\nCopyright (c) Web Semantics, Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebsemantics%2Fbuilder-extension","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebsemantics%2Fbuilder-extension","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebsemantics%2Fbuilder-extension/lists"}