-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
606 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Gamajo_Registerable | ||
|
||
Register WordPress post types and taxonomies using object-orientated design. | ||
|
||
## Description | ||
|
||
Most implementation of registering post types and taxonomies in WordPress might use classes, but these are little more than poor namespaces. Multiple post types and taxonomies are either all registered via methods in the same class, or contain duplicate code across multiple classes. I wanted to dive into how registration could be structured using something that is closer to real OOP. | ||
|
||
The code seen here is in working use on a live project. | ||
|
||
## Structure | ||
|
||
The main code is under the `Gamajo\Registerable` namespace. | ||
|
||
* `Registerable` - interface for different things that are registerable. Methods include `register()`, `unregister()`, `set_args()` and `get_args()`. | ||
* `Post_Type` - abstract class for registering post types. Implements `Registerable`, so required methods say how a post type should be registered, unregistered and how arguments should be handled. Includes abstract methods for `default_args()` and `messages()` which will contain implementation for specific post types. | ||
* `Taxonomy` - abstract class for registering taxonomies. Implements `Registerable`, so required methods say how a taxonomy should be registered, unregistered and how arguments should be handled. Includes abstract methods for `default_args()` which will contain implementation for specific taxonomies. There is a little duplication here between this and `Post_type` - either the `Registerable` could be changed from an interface to an abstract class to accommodate the common method implementations, or traits could be used if the minimum PHP version was increased from 5.2. | ||
|
||
In the `examples` directory are some example implementations, under a `Gamajo\Meal_Planner` namespace. | ||
* `Post_Type_{post type}` e.g. `Post_Type_Recipe` - specific implementation of a post type, which extends `Gamajo\Registerable\Post_Type`. Only defines the `$post_type` property, and the `default_args()` and `messages()` methods. | ||
* `Taxonomy_{taxonomy}` e.g. `Taxonomy_Recipe_Type` - specific implementation of a taxonomy, which extends `Gamajo\Registerable\Taxonomy`. Only defines the `$taxonomy` property, and the `default_args()` method. | ||
|
||
If you register multiple post types and taxonomies, you can see that only multiple classes that extend the abstract classes are needed, with specific details, creating immutable objects. The boilerplate of registering, unregistering and handling arguments don't need to be repeated. | ||
|
||
## Requirements | ||
* PHP 5.2+ | ||
|
||
## Installation | ||
|
||
This isn't a WordPress plugin on its own, so the usual instructions don't apply. Instead: | ||
|
||
1. Copy the `gamajo` files into your plugin, either manually, or via Composer. | ||
2. Ensure the classes and interfaces are available. You can `require_once` each file, if the structural element doesn't exist, or just use an autoloader (renaming anything as needed if following PSR-4). | ||
|
||
## Usage | ||
|
||
The `examples` files are examples - concrete objects of a post type and taxonomy. The only thing you need to populate for each new post type or taxonomy are the default args, and the messages. At this point, we've only created a specific post type or taxonomy class - since the class isn't instantiated, WordPress won't actually register anything. | ||
|
||
Once the classes exist, instantiating can be done with something like: | ||
|
||
```php | ||
add_action( 'init', 'prefix_mealplanner' ); | ||
/** | ||
* Kickstart the Meal Planner plugin. | ||
*/ | ||
function dt_contracts() { | ||
// Register Recipe Type taxonomy. | ||
require plugin_dir_path( __FILE__ ) . 'src/Taxonomy_Recipe_Type.php'; // Or use an autoloader. | ||
global $prefix_taxonomy_recipe_type; | ||
$prefix_taxonomy_recipe_type = new Gamajo\MealPlanner\Taxonomy_Recipe_Type; | ||
$prefix_taxonomy_recipe_type->register(); | ||
|
||
// Register Recipe post type. | ||
require plugin_dir_path( __FILE__ ) . 'src/Post_Type_Recipe.php'; // Or use an autoloader. | ||
global $prefix_post_type_recipe; | ||
$prefix_post_type_recipe = new Gamajo\MealPlanner\Post_Type_Recipe; | ||
$prefix_post_type_recipe->register(); | ||
|
||
register_taxonomy_for_object_type( $prefix_taxonomy_recipe_type->get_taxonomy(), $prefix_post_type_recipe->get_post_type() ); | ||
} | ||
``` | ||
|
||
## Contribute | ||
|
||
Issues and Pull Requests welcomed against the 'develop' branch. All code should follow the WordPress coding standards and be fully documented. | ||
|
||
## License | ||
|
||
MIT, so feel free to amend and use in any personal or commercial projects. | ||
|
||
## Credits | ||
|
||
Built by [Gary Jones](https://twitter.com/GaryJ) | ||
Copyright 2015 [Gamajo Tech](http://gamajo.com/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name" : "gamajo/registerable", | ||
"description": "A package for your WordPress core plugin, to allow registering post types and taxonomies", | ||
"keywords" : ["wordpress", "register", "custom post type", "custom taxonomy"], | ||
"homepage" : "http://github.com/gamajo/registerable", | ||
"license" : "GPL-2.0+", | ||
"authors" : [ | ||
{ | ||
"name" : "Gary Jones", | ||
"email" : "[email protected]", | ||
"homepage": "http://gamajo.com", | ||
"role" : "Developer" | ||
} | ||
], | ||
"support" : { | ||
"issues": "https://github.com/gamajo/registerable/issues" | ||
}, | ||
"require" : { | ||
"php": ">=5.4", | ||
"ext-filter": "*" | ||
}, | ||
"autoload" : { | ||
"psr-4": { | ||
"Gamajo\\Registerable\\": "src" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
/** | ||
* Meal Planner | ||
* | ||
* @package Meal_Planner | ||
* @author Gary Jones | ||
* @link http://example.com/meal-planner | ||
* @copyright 2015 Gary Jones | ||
* @license GPL-2.0+ | ||
*/ | ||
|
||
namespace Gamajo\MealPlanner; | ||
|
||
use Gamajo\Registerable\Post_Type; | ||
|
||
/** | ||
* Recipe post type. | ||
* | ||
* @package Meal_Planner | ||
* @author Gary Jones | ||
*/ | ||
class Recipe extends Post_Type { | ||
/** | ||
* Post type ID. | ||
* | ||
* @since 1.0.0 | ||
* | ||
* @var string | ||
*/ | ||
protected $post_type = 'mp_recipe'; | ||
|
||
/** | ||
* Return post type default arguments. | ||
* | ||
* @since 1.0.0 | ||
* | ||
* @return array Post type default arguments. | ||
*/ | ||
protected function default_args() { | ||
$labels = [ | ||
'name' => _x( 'Recipes', 'post type general name', 'meal-planner' ), | ||
'singular_name' => _x( 'Recipe', 'post type singular name', 'meal-planner' ), | ||
'menu_name' => _x( 'Recipes', 'admin menu', 'meal-planner' ), | ||
'name_admin_bar' => _x( 'Recipe', 'add new on admin bar', 'meal-planner' ), | ||
'add_new' => _x( 'Add New', 'mp_recipe', 'meal-planner' ), | ||
'add_new_item' => __( 'Add New Recipe', 'meal-planner' ), | ||
'new_item' => __( 'New Recipe', 'meal-planner' ), | ||
'edit_item' => __( 'Edit Recipe', 'meal-planner' ), | ||
'view_item' => __( 'View Recipe', 'meal-planner' ), | ||
'all_items' => __( 'All Recipes', 'meal-planner' ), | ||
'search_items' => __( 'Search Recipes', 'meal-planner' ), | ||
'parent_item_colon' => __( 'Parent Recipe:', 'meal-planner' ), | ||
'not_found' => __( 'No recipes found.', 'meal-planner' ), | ||
'not_found_in_trash' => __( 'No recipes found in Trash.', 'meal-planner' ), | ||
]; | ||
|
||
$supports = [ | ||
'title', | ||
'thumbnail', | ||
'revisions', | ||
'author', | ||
]; | ||
|
||
$args = [ | ||
'labels' => $labels, | ||
'supports' => $supports, | ||
'public' => true, | ||
'show_in_nav_menus' => false, | ||
'rewrite' => [ 'slug' => 'recipe' ], | ||
'menu_position' => 7, | ||
'has_archive' => 'recipes', | ||
]; | ||
|
||
return $args; | ||
} | ||
|
||
/** | ||
* Return post type updated messages. | ||
* | ||
* @since 1.0.0 | ||
* | ||
* @return array Post type updated messages. | ||
*/ | ||
public function messages() { | ||
$post = get_post(); | ||
|
||
$revision = $this->get_revision_input(); | ||
|
||
$messages = [ | ||
0 => '', // Unused. Messages start at index 1. | ||
1 => __( 'Recipe updated.', 'meal-planner' ), | ||
2 => __( 'Custom field updated.', 'meal-planner' ), | ||
3 => __( 'Custom field deleted.', 'meal-planner' ), | ||
4 => __( 'Recipe updated.', 'meal-planner' ), | ||
/* translators: %s: date and time of the revision */ | ||
5 => $revision ? sprintf( __( 'Recipe restored to revision from %s', 'meal-planner' ), wp_post_revision_title( $revision, false ) ) : false, | ||
6 => __( 'Recipe published.', 'meal-planner' ), | ||
7 => __( 'Recipe saved.', 'meal-planner' ), | ||
8 => __( 'Recipe submitted.', 'meal-planner' ), | ||
9 => sprintf( | ||
__( 'Recipe scheduled for: <strong>%1$s</strong>.', 'meal-planner' ), | ||
/* translators: Publish box date format, see http://php.net/date */ | ||
date_i18n( __( 'M j, Y @ G:i', 'meal-planner' ), strtotime( $post->post_date ) ) | ||
), | ||
10 => __( 'Recipe draft updated.', 'meal-planner' ), | ||
'view' => __( 'View recipe', 'meal-planner' ), | ||
'preview' => __( 'Preview recipe', 'meal-planner' ), | ||
]; | ||
|
||
$messages = $this->maybe_add_message_links( $messages, $post ); | ||
|
||
return $messages; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Gamajo Registerable Examples | ||
|
||
The files in this directory are example implementations of the library classes. Your implementations would go into your `plugins/{your-plugin}/includes` directory, rather than an `examples` directory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
/** | ||
* Meal Planner | ||
* | ||
* @package Meal_Planner | ||
* @author Gary Jones | ||
* @link http://example.com/meal-planner | ||
* @copyright 2015 Gary Jones | ||
* @license GPL-2.0+ | ||
*/ | ||
|
||
namespace Gamajo\MealPlanner; | ||
|
||
use Gamajo\Registerable\Taxonomy; | ||
|
||
/** | ||
* Recipe type taxonomy. | ||
* | ||
* @package Meal_Planner | ||
* @author Gary Jones | ||
*/ | ||
class Taxonomy_Recipe_Type extends Taxonomy { | ||
/** | ||
* Taxonomy ID. | ||
* | ||
* @since 1.0.0 | ||
* | ||
* @var string | ||
*/ | ||
protected $taxonomy = 'mp_recipe_type'; | ||
|
||
/** | ||
* Return taxonomy default arguments. | ||
* | ||
* @since 1.0.0 | ||
* | ||
* @return array Taxonomy default arguments. | ||
*/ | ||
protected function default_args() { | ||
$labels = [ | ||
'name' => __( 'Recipe Types', 'meal-planner' ), | ||
'singular_name' => __( 'Recipe Type', 'meal-planner' ), | ||
'menu_name' => __( 'Recipe Types', 'meal-planner' ), | ||
'edit_item' => __( 'Edit Recipe Type', 'meal-planner' ), | ||
'update_item' => __( 'Update Recipe Type', 'meal-planner' ), | ||
'add_new_item' => __( 'Add New Recipe Type', 'meal-planner' ), | ||
'new_item_name' => __( 'New Recipe Type Name', 'meal-planner' ), | ||
'parent_item' => __( 'Parent Recipe Type', 'meal-planner' ), | ||
'parent_item_colon' => __( 'Parent Recipe Type:', 'meal-planner' ), | ||
'all_items' => __( 'All Recipe Types', 'meal-planner' ), | ||
'search_items' => __( 'Search Recipe Types', 'meal-planner' ), | ||
'popular_items' => __( 'Popular Recipe Types', 'meal-planner' ), | ||
'separate_items_with_commas' => __( 'Separate recipe types with commas', 'meal-planner' ), | ||
'add_or_remove_items' => __( 'Add or remove recipe types', 'meal-planner' ), | ||
'choose_from_most_used' => __( 'Choose from the most used recipe types', 'meal-planner' ), | ||
'not_found' => __( 'No recipe types found.', 'meal-planner' ), | ||
]; | ||
|
||
$args = [ | ||
'labels' => $labels, | ||
'public' => true, | ||
'show_tagcloud' => true, | ||
'hierarchical' => false, | ||
'rewrite' => [ 'slug' => 'recipe_type' ], | ||
'show_admin_column' => true, | ||
'query_var' => true, | ||
]; | ||
|
||
return $args; | ||
} | ||
} |
Oops, something went wrong.