{"id":20945843,"url":"https://github.com/balbuf/wasp","last_synced_at":"2025-05-14T01:31:47.582Z","repository":{"id":57031968,"uuid":"105801771","full_name":"balbuf/wasp","owner":"balbuf","description":"WordPress Automated Setup Program 🐝 Write simple YAML to produce working WordPress code!","archived":false,"fork":false,"pushed_at":"2019-05-31T22:38:31.000Z","size":119,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-04-16T16:53:12.431Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/balbuf.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":"2017-10-04T18:13:14.000Z","updated_at":"2020-02-15T09:02:56.000Z","dependencies_parsed_at":"2022-08-23T20:50:08.504Z","dependency_job_id":null,"html_url":"https://github.com/balbuf/wasp","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balbuf%2Fwasp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balbuf%2Fwasp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balbuf%2Fwasp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balbuf%2Fwasp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/balbuf","download_url":"https://codeload.github.com/balbuf/wasp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224917283,"owners_count":17391823,"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-18T23:50:29.167Z","updated_at":"2024-11-18T23:50:29.702Z","avatar_url":"https://github.com/balbuf.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wasp: WordPress Automated Setup Program 🐝\n\nWasp is a tool for turning simple YAML configuration files into working WordPress code.\nUsing a variety of \"handlers\", wasp parses your configuration file and produces the necessary code\nto register post types, taxonomies, menus, and much more! Wasp reduces the tedious nature of this\nwork by leveraging sensible defaults and accepting user-defined defaults for complete flexibility.\n\nWasp is best employed as part of your build process, which means only the YAML file(s) would be stored in\nyour version control system. In the course of a build process, wasp parses the configuration file and\ngenerates a PHP file that can act as the `functions.php` file of a theme, the main plugin file of a plugin,\nthe entirety of an mu-plugin, or a file that is included by any of the former. However, wasp can also be used\nto generate code that you can use as a starting point for your project, allowing you to save and modify it from\nthere. As such, if at any point you want to ditch wasp, you'd simply need to generate your code, save it, and\nremove wasp from your project. Wasp gives you the benefit of a theme or plugin framework without ever having\nto commit!\n\n## Installing\n\nThe preferred way to install wasp is via [Composer](https://getcomposer.org/):\n\n```sh\n$ composer require balbuf/wasp --dev\n```\n\nWasp will now be available in composer's [\"bin dir\"](https://getcomposer.org/doc/articles/vendor-binaries.md), which is located in `vendor/bin` by default.\nYou should be able to run wasp via:\n\n```sh\n$ vendor/bin/wasp\n```\n\nWasp doesn't come with any handlers out of the box, so that you can leverage only the features you want and nothing more.\nIn order to get started, you'll need to install one or more wasp plugins that contain handlers.\nAll of the essential handlers for basic WordPress configuration can be found in [balbuf/wasp-core](https://github.com/balbuf/wasp-core):\n\n```sh\n$ composer require balbuf/wasp-core --dev\n```\n\n## Creating a Config YAML File\n\nThe config YAML file can be named anything you'd like and stored anywhere, too.\nWhen you run the `generate` command, you will specify the location of your config file.\nThe only stipulation is that the file contain valid YAML and data that is properly formatted for each of your handlers.\n\nThe properties you set inside of your YAML file will depend upon the handlers you intend to use.\nTypically, one top-level property will be used by a single handler, but sometimes multiple handlers\nwill act upon the same property for different purposes, or a handler may reference properties outside\nof the main one it handles to obtain additional information.\n\nAll config files should contain an `wasp` property, which defines details about the file itself, e.g.:\n\n```yml\nwasp:\n  # a unique prefix used to differentiate this project from others\n  prefix: wasp_example\n\n  # location of this file relative to the file root of the project\n  dir: inc\n\n  # how wasp should determine the public URL that corresponds to the file root of the project\n  url_context: plugin\n```\n\nAdditional properties will depend on the handlers you wish to use, and you should consult the documentation\nfor the handlers' respective wasp plugin(s).\n\n## Generating Code\n\nGenerating code requires an input file path (to your YAML config file) and an output file path (to the generated PHP code), e.g.:\n\n```sh\n$ vendor/bin/wasp generate config.yml themes/my-theme/functions.php\n```\n\nThe input file path and/or output file path can be replaced by `-` to read data from `STDIN` or write data\nto `STDOUT`, respectively.\n\nSome handlers that work with additional files in your project (e.g. handlers that help with including files,\nenqueing front-end assets, etc.) will need to know the path to your project's file root. The file root,\nfor example, would be the directory that contains your `functions.php` file for a theme or the main\nplugin file for a plugin. Knowing the location of the file root on the filesystem and the relative location of your\ngenerated file within (specified via the `wasp.dir` property of your config file) allows handlers to analyze files\non the filesystem and properly reference them from the generated PHP file.\n\nIn most cases, the file root can be discerned based on the output file path provided via the command line, in\ncombination with the `wasp.dir` property specified in the config file. However, in the case of writing to\n`STDOUT`, explicitly specifying the project's file root may be required. For instance, the example above\ncould be rewritten as:\n\n```sh\n$ vendor/bin/wasp generate config.yml - --root=themes/my-theme \u003e themes/my-theme/functions.php\n```\n\nIf not specified or discernable from the output path, the file root defaults to the current working directory.\n\n## Adding Handlers\n\nHandlers are typically added to your project by installing additional wasp plugins via composer. When wasp runs,\nit analyzes your project's `composer.lock` file to identify and execute all wasp plugins.\n\nConsidering all plugins/handlers installed in your project are activated by default, at times you may wish\nto disable certain plugins and/or handlers when generating your code.\n\n- To disable a plugin, use the `--disable-plugin=` option along with the composer package name for the plugin\n- To disable a handler, use the `--skip-handler=` option along with the handler's machine name\n\nEither option may be repeated to disable multiple plugins and/or handlers.\n\n## Wasp Config Properties\n\nThe `wasp` top-level property contains information about the project and controls how code is generated.\n\n| Property | Description |\n| --- | --- |\n| `prefix` | The prefix is required and should be unique for the particular component you are generating, which helps to avoid collisions with other components (e.g. if a WordPress site was using multiple plugins that were built with wasp). |\n| `dir` | This specifies where the generated file is located on the filesystem relative to the file root. For instance, if the generated file was located at `themes/my-theme/inc/config.php` for the theme located in `themes/my-theme`, the value for `dir` should be `inc`. The default value is the file root itself. |\n| `url_context` | The URL context helps wasp determine the public URL that corresponds to the file root, which is necessary for things like enqueing frontend assets. If you are creating a plugin or a theme and the file root corresponds to the plugin/theme's top-level directory, you can use `plugin` or `theme`, respectively. For custom setups, the URL context can be a URL pattern with a replacement token for one of the WordPress URL functions (e.g. using `home_url()` like `%home_url%/wp-content/themes/my-theme/`) or a hard-coded URL that points to the file root (e.g. `https://example.com/wp-content/themes/my-theme/`). The URL replacement tokens all correspond to the WordPress function of the same name and include: `%home_url%`, `%site_url%`, `%admin_url%`, `%includes_url%`, `%content_url%`, `%plugins_url%`, `%theme_url%`, `%get_stylesheet_directory_uri%`, and `%get_template_directory_uri%` . |\n| `vars` | This is a convenient place to set variables that can be used throughout the config file (see Advanced Config below). |\n\n## Advanced Config\n\nWasp uses [Twig](https://twig.symfony.com/doc/1.x/) to process its config values, allowing the user to reference\nother properties within the config and perform some basic value processing via Twig's filters, functions, etc.\nIn order to use Twig in your config property values, you must enclose some or all of the value in Twig template\ndelimeters: `{{ }}` for expressions and `{% %}` for more complex control structures (loops, logic, etc.).\n(Note that when a property value starts with a Twig template, the value must be quoted, otherwise the YAML\nparser will get confused and interpret the value as an inline object, e.g. `property: '{{ template }}'` instead\nof the invalid `property: {{ template }}`.)\n\n### Special Variables\n\nWithin a config property template, there are a number of special variables which allow access to surrounding property\nvalues, the current property chain, etc.\n\n| Variable | Description |\n| --- | --- |\n| `this` | a reference to the property's direct parent config object to easily access the value of its sibling properties, e.g. `this.sibling_prop`; to ascend further up the property chain, simply append `.parent` as necessary, e.g. `this.parent.parent.property` |\n| `top` | a reference to the top-level config object, allowing access to any property in the config file |\n| `vars` | a shortcut reference to `top.wasp.vars` which provides a convenient way to reuse config-wide variables |\n| `prop` | an array of the current property chain, with the current property being index 0 and working backwards |\n| `env` | a simple object with a `set()` method (which sets public properties that can then be accessed directly) that is shared amongst a property value template and any referenced property value templates, allowing communication with each other during value resolution; for example, calling `env.set('foo', 'bar')` allows accessing the value `bar` via `env.foo` |\n\nBecause Twig is meant to be a templating engine which ultimately produces strings, special handling is necessary to\nproduce a non-string value for a property. An additional variable called `output` is provided which has a `setValue()`\nmethod to override the resolved value of the property template, e.g. `{% do output.setValue([\"this\", \"produces\", \"an\", \"array\"]) %}`.\nSimilarly, the special `this`, `top`, and `vars` variables return strings for other property values by default.\nTo access a property value of another type, the property must be appended with `.getValue()`, e.g. `this.sibling_prop.getValue()`;\nas a shortcut, the property name can be appended with `()` to access the raw value, e.g. `this.sibling_prop()`.\n\n### User Defaults\n\nFor many handlers whose property structure is an associative array of associative arrays, wasp provides a\nconvenient way to provide default values to fill in those second-level associative arrays. To illustrate\nthis type of property structure:\n\n```yml\nhandler_property:\n\n  thing1:\n    name: Thing 1\n    color: red\n\n  thing2:\n    name: Thing 2\n```\n\nNotice how the handler's property is an associative array where the key (e.g. `thing1`) represents a slug\n(machine friendly identifier) for the item and the value of the item is another associative array containing\nthe item's properties and values (e.g. `name`, `color`, etc.). When the item arrays have many possible properties,\nit's not uncommon to find yourself repeating the same value again and again for each item.\n\nIn order to reduce repetition, you can add a `default` item whose properties are filled in for all the other items\nwhen not explicitly set, e.g.:\n\n```yml\nhandler_property:\n\n  default:\n    color: blue\n    name: Untitled\n\n  thing1:\n    name: Thing 1\n    color: red\n\n  thing2:\n    name: Thing 2\n```\n\nSince `thing2` did not specify a `color` property, it inherits the `color` value from the `default` item (blue).\n\n#### Self-referential Property Templates\n\nAnother feature of the default item is the ability to reference the same property in the main items when the items'\nproperty values are resolved. Instead of just providing default values, the default item can also _alter_ the\nvalues of the properties in each main item. To make a self-referential template, the `this` keyword can be used.\nIn the following example, we use the default `post_type` property to add a prefix to the post type slug:\n\n```yml\npost_types:\n\n  default:\n    post_type: wasp_{{ this }}\n\n  event:\n    post_type: event\n\n  testimonial:\n    post_type: testimonial\n```\n\nWhen this config is resolved, the `post_type` property for our items will be `wasp_event` and `wasp_testimonial`,\nrespectively.\n\n### Recipes\n\nThe advanced config using Twig can be a little complicated, so here are some example \"recipes\" to help illustrate\nthe potential and allow you to get the most out of your config file with the least amount of work.\n\n#### Conditional Prefix\n\nThe prefixed-post-type example above is great, but there are instances where you might need to use the `post_type`\nwasp handler to modify a built-in post type or one provided by a plugin. In these instances, adding a prefix\nto the post type value would be incorrect. We can make use of the `env` object to turn off the prefix for\ncertain items, e.g.:\n\n```yml\npost_types:\n\n  default:\n    post_type: '{% if not env.noPrefix %}wasp_{{ this }}{% endif %}'\n\n  event:\n    post_type: event\n\n  testimonial:\n    post_type: testimonial\n\n  post:\n    post_type: post{% do env.set('noPrefix', true) %}\n```\n\nNow the resolved `post_type` properties will be `wasp_event`, `wasp_testimonial`, and `post`.\n\nThis could also be achieved by adding a custom property to the item:\n\n```yml\npost_types:\n\n  default:\n    post_type: '{% if not this.no_prefix %}wasp_{{ this }}{% endif %}'\n\n  event:\n    post_type: event\n\n  testimonial:\n    post_type: testimonial\n\n  post:\n    post_type: post\n    no_prefix: true\n```\n\nThis can make the config look a little cleaner, but the possible disadvantage is that the `no_prefix` value\nwill be passed on to any handlers. In most cases the handler will ignore any properties it isn't expecting,\nbut the custom property could cause unintended consequences with some handlers.\n\n#### Suffix with Default Value\n\nSuppose you want to leverage a self-referential template while still providing a default value in case\nthe property was not set in one of the main items. This is possible, too! Take this imaginary `images`\nhandler, where we want to have a `.jpeg` file extension automatically added to the `file` property value,\nwhile still providing a fallback file value:\n\n```yml\nimages:\n\n  default:\n    file: '{{ ( this ?: \"placeholder\" ) ~ \".jpeg\" }}'\n\n  pic1:\n    file: kittens\n    alt: Kittens playing!\n\n  pic2:\n    file: puppies\n    alt: Puppies playing!\n\n  pic3:\n    alt: Image coming soon!\n```\n\nWhen the config is resolved, the values of the file property will be `kittens.jpeg`, `puppies.jpeg`, and `placeholder.jpeg`.\n\n#### Default Array Values\n\nWhen specifying script dependencies, it's not uncommon for many or all to require `jquery`. We can set\nthis script (and any others) as the default base dependencies with the use of a `default` object and a\ncustom property. The `scripts` handler will look for the `dependencies` property, so we will leverage\nthat property in the `default` item and a custom property (`additional_dependencies`) to merge our base\nscript dependencies with any additional dependencies for each item:\n\n```yml\nscripts:\n\n  default:\n    dependencies: '{% set deps = [\"jquery\"] %}{% do output.setValue(this ?: (this.additional_dependencies() is iterable ? this.additional_dependencies() | merge(deps) : deps)) %}'\n\n  main:\n    additional_dependencies:\n      - jquery-ui\n\n  navigation:\n    dependencies:\n      - underscore\n```\n\nFor the `main` item, it declares additional dependencies of `jquery-ui`, causing it to use the default base\ndependencies and producing `['jquery', 'jquery-ui']`. For the `navigation` item, we don't need `jquery`, so\nwe use the `dependencies` property directly; the logic in our default `dependencies` property respects this\nand produces `['underscore']` for this item.\n\n## Extending\n\nTODO: creating plugins, creating handlers, creating compilables, using compilables, including files, etc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalbuf%2Fwasp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbalbuf%2Fwasp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalbuf%2Fwasp/lists"}