{"id":50451658,"url":"https://github.com/posty-studio/posty-starter-plugin","last_synced_at":"2026-06-01T00:05:19.504Z","repository":{"id":143937771,"uuid":"255879998","full_name":"posty-studio/posty-starter-plugin","owner":"posty-studio","description":"🎴 An opinionated WordPress starter plugin.","archived":false,"fork":false,"pushed_at":"2023-10-17T17:21:14.000Z","size":56,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-10-17T18:42:27.814Z","etag":null,"topics":["block-editor","gutenberg","starter-plugin","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/posty-studio.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}},"created_at":"2020-04-15T10:16:00.000Z","updated_at":"2023-05-29T22:03:16.000Z","dependencies_parsed_at":"2023-10-17T19:45:19.311Z","dependency_job_id":null,"html_url":"https://github.com/posty-studio/posty-starter-plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/posty-studio/posty-starter-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posty-studio%2Fposty-starter-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posty-studio%2Fposty-starter-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posty-studio%2Fposty-starter-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posty-studio%2Fposty-starter-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/posty-studio","download_url":"https://codeload.github.com/posty-studio/posty-starter-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posty-studio%2Fposty-starter-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33753956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["block-editor","gutenberg","starter-plugin","wordpress"],"created_at":"2026-06-01T00:05:18.591Z","updated_at":"2026-06-01T00:05:19.499Z","avatar_url":"https://github.com/posty-studio.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Posty Starter Plugin\n\nAn opinionated starter plugin for WordPress.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Development](#development)\n- [Build](#build)\n- [Features](#features)\n  * [Custom Post Types](#custom-post-types)\n  * [Taxonomies](#taxonomies)\n  * [Assets](#assets)\n  * [Blocks](#blocks)\n  * [Helpers](#helpers)\n- [License](#license)\n\n## Installation\n\nClone or copy the contents of the repository, then run `npm install` or `yarn install` to get started.\n\nThere's a few placeholders that need to be replaced. Please note that these are case-sensitive. For example. if your plugin is named `lion-king-quote-generator`, you'd rename like this:\n\n| Original                   | Replacement                     | Used For                         |\n|----------------------------|---------------------------------|----------------------------------|\n| `posty-starter-plugin.php` | `lion-king-quote-generator.php` | The base plugin file             |\n| `Posty_Starter_Plugin`     | `Lion_King_Quote_Generator`     | PHP classes namespace            |\n| `posty-starter-plugin`     | `lion-king-quote-generator`     | Textdomain and block name prefix |\n| `POSTY_STARTER_PLUGIN`     | `LION_KING_QUOTE_GENERATOR`     | Constants                        |\n| `postyStarterPlugin`       | `LionKingQuoteGenerator`        | JavaScript l10n variable*        |\n\n*\\*This is the `$object_name` variable when [localizing a script](https://developer.wordpress.org/reference/functions/wp_localize_script/) in the `Assets` class.*\n\n## Development\n\nRun `npm run start` to start developing. Webpack will automatically process style and script changes.\n\n## Build\n\nRun `npm run build` to compile and minify all assets.\n\n## Features\n\nPosty Starter Plugin has a bunch of features that enable you to get productive right from the start.\n\n### Custom Post Types\n\nTo register a new custom post type, you need to extend the `Custom_Post_Types/Base` class like so:\n\n```php\nclass Event extends Base {\n    const NAME = 'posty-event';\n\n    /**\n     * Register the custom post type.\n     */\n    public static function register() {\n        $options = [\n            'slug' =\u003e __('event', 'posty-starter-plugin'),\n            'singular' =\u003e __('Event', 'posty-starter-plugin'),\n            'plural' =\u003e __('Events', 'posty-starter-plugin'),\n            'args' =\u003e [\n                'menu_icon' =\u003e 'dashicons-calendar'\n            ]\n        ];\n\n        parent::register_cpt(self::NAME, $options);\n    }\n}\n```\n\nThis creates the `posty-event` post type. The `slug`, `singular` and `plural` options are mandatory, and the `args` option allows you to overwrite any option passed to [register_post_type](https://developer.wordpress.org/reference/functions/register_post_type/).\n\nYou can also add custom labels like so:\n\n```php\n$options = [\n    'slug' =\u003e __('event', 'posty-starter-plugin'),\n    'singular' =\u003e __('Event', 'posty-starter-plugin'),\n    'plural' =\u003e __('Events', 'posty-starter-plugin'),\n    'labels' =\u003e [\n        'add_new' =\u003e __('Add a new event', 'posty-starter-plugin')\n    ],\n    'args' =\u003e [\n        'menu_icon' =\u003e 'dashicons-calendar'\n    ]\n];\n```\n\nThe nice thing about registering custom post types like this is that you can extend these classes with any kind of functionality related to the post type. For example, you might want the ability to get the latest three events. You could add it like this:\n\n```php\n/**\n * Get the latest events.\n *\n * @return WP_Post[]\n */\npublic static function latest() {\n    return get_posts([\n        'post_type' =\u003e self::NAME,\n        'posts_per_page' =\u003e 3\n    ]);\n}\n```\n\nThen, in your code you can use this function to easily display the latest three events:\n\n```php\nuse Posty_Starter_Plugin\\Custom_Post_Types\\Event;\n\n$events = Event::latest();\n\nforeach ($events as $event) {\n    echo $event-\u003epost_title;\n}\n```\n\nA similar method could be used to implement functionality related to a single event. For example, let's say you have a meta field `event_ticket_price` that contains the price of an event. You could add this code to your `Event` class to easily obtain this price:\n\n```php\n/**\n * Get the ticket price of an event.\n *\n * @param WP_Post|int $event\n * @return string\n */\npublic static function ticket_price($event = null) {\n    $event = get_post($event);\n\n    return get_post_meta($event-\u003eID, 'event_ticket_price', true);\n}\n```\n\n```php\nuse Posty_Starter_Plugin\\Custom_Post_Types\\Event;\n\n$ticket_price = Event::ticket_price();\n\necho $ticket_price;\n```\n\nBy adding `$event = get_post($event)`, the function defaults to the current event, but also allows you to get the price of a specific event by passing the post ID or a `WP_Post` object.\n\n### Taxonomies\n\nTaxonomies work almost exactly the same as [custom post types](#custom-post-types). One difference is that you can also pass the `object_type` option to link the taxonomy to a specific post type. See the `Event_Category` class for an example.\n\n### Assets\n\nThe `Assets` class takes care of registering styles and scripts. The [@wordpress/scripts](https://developer.wordpress.org/block-editor/packages/packages-scripts/) package is used to automatically list the dependencies needed for each scripts.\n\nThe code in `editor/index.js` only runs in the Block Editor, and the code in `frontend/index.js` only runs on the frontend of the site. The same principles apply to `editor.css` and `frontend.css`\n\n*Note: if you want to use Sass instead of CSS, install and add [sass-loader](https://github.com/webpack-contrib/sass-loader) to `webpack.config.js`.*\n\n### Blocks\n\nA big focus of the Posty Starter Plugin is making it as easy as possible to register blocks. All blocks can be found in the `src/js/editor/blocks` folder and are initialized in `src/js/editor/index.js`. To render a server-side block, add a template file with the same name as the block to the `templates/blocks` folder.\n\nFor more information on developing blocks, please refer to the [Block API Reference](https://developer.wordpress.org/block-editor/developers/block-api/).\n\n### Helpers\n\nIn `helpers.php`, you can find a collection of custom helper functions as well as add your own.\n\n#### `classes`\n\n`classes` is similar to the very popular [classNames](https://github.com/JedWatson/classnames) package for JavaScript, and allows you to conditionally add classes to an HTML element. It's based on [classnames-php](https://github.com/cstro/classnames-php).\n\nUse it like this:\n\n```php\nPosty_Starter_Plugin\\classes('foo'); // 'foo'\nPosty_Starter_Plugin\\classes(['foo' =\u003e true]); // 'foo'\nPosty_Starter_Plugin\\classes('foo', ['bar' =\u003e false, 'baz' =\u003e true]); // 'foo baz'\nPosty_Starter_Plugin\\classes(['foo', 'bar' =\u003e true]) // 'foo bar'\n\n// Falsy values get ignored\nPosty_Starter_Plugin\\classes('foo', null, 0, false, 1); // 'foo 1'\n```\n\n#### `get_template` and `get_template_var`\n\nThese two functions allow you to render template parts from the `templates` folder with custom parameters. To demonstrate how this works, here's an example. Let's say you have a template part, `templates/hello.php`, that looks like this:\n\n```php\n$name = 'Phil';\n\necho \"Hello, my name is {$name}.\";\n```\n\nThis would output *Hello, my name is Phil*. To render this template part, you can use the `get_template` helper function:\n\n```php\necho Posty_Starter_Plugin\\get_template('hello');\n```\n\nHowever, you might also want to want to make the name dynamic. To allow this, `get_template` accepts an array of parameters:\n\n```php\necho Posty_Starter_Plugin\\get_template('hello', [\n    'name' =\u003e 'Lindsay'\n]);\n```\n\nTo use the dynamic name, you'd change `templates/hello.php` to this:\n\n```php\n$name = Posty_Starter_Plugin\\get_template_var('name');\n\necho \"Hello, my name is {$name}.\";\n```\n\n## License\n\n[GPL 3.0](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposty-studio%2Fposty-starter-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposty-studio%2Fposty-starter-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposty-studio%2Fposty-starter-plugin/lists"}