-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial: Creating a Custom Plugin to Extend the CYOA Plugin
Creating a custom WordPress plugin that adds new entity types—such as Items, Weapons, Vehicles, Locations, Lore, Organizations, and Laws—to your CYOA (Choose Your Own Adventure) Story Builder plugin using Advanced Custom Fields (ACF). This approach allows us to extend the functionality without modifying the original plugin.
This plugin will:
- Register custom post types for your entities (Items, Weapons, Vehicles, Locations, Lore, Organizations, and Laws).
- Use Advanced Custom Fields (ACF) to add custom fields to these entities.
- Integrate with your existing templates to display entity information.
- Navigate to your WordPress installation's
wp-content/plugins
directory. - Create a new folder named
cyoa-entities
. - Inside this folder, create a file named
cyoa-entities.php
.
In cyoa-entities.php
, add the following code at the top:
<?php
/*
Plugin Name: CYOA Entities
Description: Adds custom post types and integrates entities with the CYOA Story Builder plugin.
Version: 1.0
Author: Your Name
Text Domain: cyoa-entities
*/
This header provides WordPress with the necessary information about your plugin.
We'll register CPTs for each entity type using the register_post_type
function.
Add the following code to cyoa-entities.php
:
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Register custom post types
function cyoa_register_custom_post_types() {
$entity_types = [
'iasb_lore' => 'Lore',
'iasb_organization' => 'Organization',
'iasb_law' => 'Law',
];
foreach ( $entity_types as $slug => $singular ) {
$plural = $singular . 's';
$labels = [
'name' => $plural,
'singular_name' => $singular,
'menu_name' => $plural,
'name_admin_bar' => $singular,
'add_new' => 'Add New',
'add_new_item' => 'Add New ' . $singular,
'new_item' => 'New ' . $singular,
'edit_item' => 'Edit ' . $singular,
'view_item' => 'View ' . $singular,
'all_items' => 'All ' . $plural,
'search_items' => 'Search ' . $plural,
'not_found' => 'No ' . strtolower( $plural ) . ' found.',
'not_found_in_trash' => 'No ' . strtolower( $plural ) . ' found in Trash.',
'parent_item_colon' => '',
'menu_name' => $plural,
];
$args = [
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => [ 'slug' => strtolower( $plural ) ],
'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ],
'show_in_rest' => true, // Enables Gutenberg editor support
'taxonomies' => [],
];
register_post_type( $slug, $args );
}
}
add_action( 'init', 'cyoa_register_custom_post_types' );
Explanation:
-
Prevent Direct Access: The check for
ABSPATH
ensures the file is not directly accessed. -
Function
cyoa_register_custom_post_types()
: Registers each entity type as a custom post type. -
Entity Types: Uses your specified slugs with the
iasb_
prefix to avoid conflicts. - Labels and Arguments: Sets up the necessary labels and arguments for each CPT.
Since you want to use ACF to add custom fields without adding more features to the plugin, we won't include code for custom fields in the plugin. Instead, we'll guide you on setting up ACF fields.
- Go to Plugins > Add New in your WordPress dashboard.
- Search for Advanced Custom Fields.
- Install and activate the plugin by WP Engine.
You'll need to create field groups for each entity type.
-
Navigate to: Custom Fields > Add New.
-
Field Group Title: Item Fields.
-
Location Rules: Show this field group if Post Type is equal to Item (
iasb_item
). -
Add Fields:
-
Item Type
- Field Label: Item Type
- Field Name:
item_type
- Field Type: Select
- Choices: Add options like
Consumable
,Equipment
,Quest Item
, etc.
-
Rarity
- Field Label: Rarity
- Field Name:
rarity
- Field Type: Select
- Choices:
Common
,Uncommon
,Rare
,Epic
,Legendary
-
Value
- Field Label: Value
- Field Name:
value
- Field Type: Number
-
Description
- Field Label: Description
- Field Name:
description
- Field Type: Textarea
-
-
Publish the field group.
Repeat this process for other entity types, adding relevant fields.
Now, we'll integrate your provided item and story templates.
-
Item Template:
single-iasb_item.php
-
Story Template:
single-iasb_story.php
Place these files in your theme's folder. If your theme doesn't support custom templates for CPTs, you may need to modify it or use a child theme.
Use your provided item template code. Create a file named single-iasb_item.php
in your theme directory and add the following code:
<?php
// single-iasb_item.php
get_header();
if (have_posts()) :
while (have_posts()) : the_post();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class('story_builder item_builder'); ?>>
<!-- Title -->
<h1 class="story-story-title"><?php the_title(); ?></h1>
<!-- Featured Image (Optional) -->
<?php if (has_post_thumbnail()) : ?>
<div class="item-image">
<?php the_post_thumbnail('large', array('alt' => get_the_title())); ?>
</div>
<?php endif; ?>
<!-- Meta Information -->
<div class="story-story-meta item-meta">
<?php
// Display item type from ACF field
$item_type = get_field('item_type');
if ($item_type) {
echo '<span class="item-type"><i class="fas fa-archive"></i> <strong>' . __('Type:', 'story-builder') . '</strong> ' . esc_html($item_type) . '</span>';
}
?>
</div>
<!-- Content -->
<div class="story-content item-content">
<?php
// Display the description from ACF field
$description = get_field('description');
if ($description) {
echo wpautop($description);
} else {
the_content();
}
?>
</div>
<?php
// Allow themes/plugins to add additional content after item content
do_action('iasb_after_item_content', get_the_ID());
?>
</article>
<?php
endwhile;
endif;
get_footer();
Explanation:
-
Meta Information: Retrieves and displays the
item_type
field from ACF. -
Content: Displays the
description
field from ACF if available; otherwise, it displays the post content.
Create a file named single-iasb_story.php
in your theme directory and add the following code:
<?php
// single-iasb_story.php
get_header();
if (have_posts()) :
while (have_posts()) : the_post();
// Get the current post ID and user ID
$post_id = get_the_ID();
$user_id = get_current_user_id();
// Existing code to handle universes and user progress...
?>
<article id="post-<?php the_ID(); ?>" <?php post_class('story_builder'); ?>>
<h1 class="story-story-title"><?php the_title(); ?></h1>
<div class="story-story-meta">
<?php
// Display breadcrumb navigation
// iasb_display_breadcrumbs($post_id);
?>
</div>
<?php if (has_post_thumbnail()) : ?>
<div class="single-story-image">
<?php the_post_thumbnail('large', array('alt' => get_the_title())); ?>
</div>
<?php endif; ?>
<div class="story-content">
<?php the_content(); ?>
</div>
<?php
// Existing code for universes, user progress, etc.
// Display Entities Associated with the Story
?>
<div class="story-entities">
<?php
// Function to display entities
function iasb_display_entities($post_id, $field_name, $entity_label) {
$entities = get_field($field_name, $post_id);
if ($entities) {
echo '<h3>' . sprintf(__('Related %s:', 'story-builder'), $entity_label) . '</h3>';
echo '<ul>';
foreach ($entities as $entity) {
echo '<li><a href="' . get_permalink($entity->ID) . '">' . get_the_title($entity->ID) . '</a></li>';
}
echo '</ul>';
}
}
// Display Items
iasb_display_entities($post_id, 'iasb_story_items', 'Items');
// Display Weapons
iasb_display_entities($post_id, 'iasb_story_weapons', 'Weapons');
// Display Vehicles
iasb_display_entities($post_id, 'iasb_story_vehicles', 'Vehicles');
// Display Locations
iasb_display_entities($post_id, 'iasb_story_locations', 'Locations');
// Display Lore
iasb_display_entities($post_id, 'iasb_story_lore', 'Lore');
// Display Organizations
iasb_display_entities($post_id, 'iasb_story_organizations', 'Organizations');
// Display Laws
iasb_display_entities($post_id, 'iasb_story_laws', 'Laws');
?>
</div>
</article>
<?php
endwhile;
endif;
get_footer();
Explanation:
-
Function
iasb_display_entities()
: A helper function to display entities associated with the story. -
Displaying Entities: Calls
iasb_display_entities()
for each entity type, passing the ACF field name and label. - ACF Fields in Story: Ensure you've added ACF relationship fields to associate entities with stories (covered in Step 5).
To associate entities with stories, we'll add relationship fields to the Story post type.
-
Navigate to: Custom Fields > Add New.
-
Field Group Title: Story Entities.
-
Location Rules: Show this field group if Post Type is equal to Story (
iasb_story
or your story CPT). -
Add Fields:
-
Items
- Field Label: Items
- Field Name:
iasb_story_items
- Field Type: Relationship
- Post Type Filter: Select Items (
iasb_item
).
-
Weapons
- Field Label: Weapons
- Field Name:
iasb_story_weapons
- Field Type: Relationship
- Post Type Filter: Select Weapons (
iasb_weapon
).
-
Vehicles
- Field Label: Vehicles
- Field Name:
iasb_story_vehicles
- Field Type: Relationship
- Post Type Filter: Select Vehicles (
iasb_vehicle
).
-
Locations
- Field Label: Locations
- Field Name:
iasb_story_locations
- Field Type: Relationship
- Post Type Filter: Select Locations (
iasb_location
).
-
Lore
- Field Label: Lore
- Field Name:
iasb_story_lore
- Field Type: Relationship
- Post Type Filter: Select Lore (
iasb_lore
).
-
Organizations
- Field Label: Organizations
- Field Name:
iasb_story_organizations
- Field Type: Relationship
- Post Type Filter: Select Organizations (
iasb_organization
).
-
Laws
- Field Label: Laws
- Field Name:
iasb_story_laws
- Field Type: Relationship
- Post Type Filter: Select Laws (
iasb_law
).
-
-
Publish the field group.
- Go to Plugins in your WordPress dashboard.
- Find CYOA Entities in the list.
- Click Activate.
- Go to Items > Add New.
- Enter the item title.
- Fill in the ACF fields (Item Type, Rarity, Value, Description).
- Add a featured image if desired.
- Publish the item.
Repeat similar steps for Weapons, Vehicles, Locations, Lore, Organizations, and Laws.
- Edit a story post.
- In the Story Entities metabox (added via ACF), select the entities related to the story.
- Update or publish the story.
- View a story on the frontend.
- Confirm that the associated entities are displayed correctly in the story-entities section.
- View an item page to ensure the custom fields are displayed as per the item template.
Here's the complete cyoa-entities.php
file:
<?php
/*
Plugin Name: CYOA Entities
Description: Adds custom post types and integrates entities with the CYOA Story Builder plugin.
Version: 1.0
Author: Your Name
Text Domain: cyoa-entities
*/
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Register custom post types
function cyoa_register_custom_post_types() {
$entity_types = [
'iasb_lore' => 'Lore',
'iasb_organization' => 'Organization',
'iasb_law' => 'Law',
];
foreach ( $entity_types as $slug => $singular ) {
$plural = $singular . 's';
$labels = [
'name' => $plural,
'singular_name' => $singular,
'menu_name' => $plural,
'name_admin_bar' => $singular,
'add_new' => 'Add New',
'add_new_item' => 'Add New ' . $singular,
'new_item' => 'New ' . $singular,
'edit_item' => 'Edit ' . $singular,
'view_item' => 'View ' . $singular,
'all_items' => 'All ' . $plural,
'search_items' => 'Search ' . $plural,
'not_found' => 'No ' . strtolower( $plural ) . ' found.',
'not_found_in_trash' => 'No ' . strtolower( $plural ) . ' found in Trash.',
'parent_item_colon' => '',
'menu_name' => $plural,
];
$args = [
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => [ 'slug' => strtolower( $plural ) ],
'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ],
'show_in_rest' => true,
'taxonomies' => [],
];
register_post_type( $slug, $args );
}
}
add_action( 'init', 'cyoa_register_custom_post_types' );
-
Custom Taxonomies: If you need taxonomies (e.g., categories or tags) for your entities, you can register them similarly using
register_taxonomy
. - Template Hierarchy: Ensure your theme supports custom templates for CPTs. If not, you may need to create a child theme or modify your theme.
- Styling: Add CSS styles to your theme or plugin to style the entity displays.
- ACF Pro Features: If you have ACF Pro, you can use features like Repeater Fields and Flexible Content for more advanced custom fields.
By creating this custom plugin, you've extended the functionality of your CYOA Story Builder plugin to include new entity types, leveraging ACF for custom fields. This approach keeps your customizations modular and maintainable.