Wordpress Private Custom Post Type (CPT) for Dynamic Content
Tags: wordpress, php, beginners, tutorial
Published: 2023-02-02 02:32:06

*WordPress*, a content management system, have a default **Posts** action that is geared towards blogging. This make *WordPress* default **Posts** action unsuitable for dynamic content as managing various items such as product items, blog posts, services, etc… in only one places will make your backend messy very quickly. To solve this, **Custom Post Type** will be utilized to keep everything tidy and easy to organize.

We would have to install some plugins to enable **Custom Post Type**, as *WordPress* doesn't have this feature natively. These are the plugins that will be used to accomplish it:

- [Advanced Custom Fields](https://wordpress.org/plugins/advanced-custom-fields/)

- [Custom Post Type UI](https://wordpress.org/plugins/custom-post-type-ui/)

In this article, only the free version is required to make this work, so you don't have to worry about upgrading to the premium version to follow along.

## Getting Started with ACS

1. Firstly, install two of these plugins at the **Plugins section**, and activate them once the installation is finished.

2. You should now see a new entry called **Custom Fields** at the sidebar if your installation is successful, like the figure below.
   ![Figure 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ejpqzjvelcanoo5222c.jpg)
   Now, hover over **Custom Fields** and select *Add New*, this will let you create a new **Meta Field Group**, which can group your content in a meaningful way and makes organizing easier. For example, you may have one group named *Products*, and have another named *Achievements*, so you can add your content to the respective collection instead of mixing up everything in the default **Post** collection.

3. You should see the interface like the figure below when you are on *Add New* section.
   ![Figure 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dtmfcv6smub0yyutm5b6.jpg)
   Think of a meaningful name for your **Field Group** name and enter it in the **Add New Field Group** input box. At the **Settings** section, the **Location Rules**, just leave it be like the figure above, we will change that afterward. Then, click open the **Fields** option, and you are able to add various type of input fields for the content.
   ![Figure 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vbqrog6910k8ee7d4794.jpg)
4. At the **Field Type**, there are quite a few option for you to pick at the dropdown menu that fits your content requirements. For example, if you wish to have your employee to be presented, you may need your *employee name* as `Text` field, *age* as `Number`, *email address* as `Email`, personal website as `Url`, and so on.
   ![Figure 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8281l627vgaxujbz7any.jpg)
   Enter your **Field Label**, and it will automatically add a **Field Name** for you. You may have a default value if you require it, but in this specific example, no default value is needed, so just leave it empty.
5. When you are finished with **General** tab, move on to **Validation** tab, in here you will see two option, **Required** and **Character Limit**. You may set this field as a required field at the *Name* field as your employee must have had a name, but for fields like *Personal Website*, you might not want to make it a *required* field as not everyone have one. You may also specify the maximum character limit to prevent overly long character count to ruin your UI. If you need none of these, just leave it be.
   ![Figure 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygpszhre11zvi3lsi4y3.jpg)
6. For the **Presentation** tab, you may add more customization and info for yourself or anyone that need to add or update the content. You are able to add Instructions to remind the people editing the content, add a placeholder text to give tips of the field value to enter, **Append** or **Prepend** character that have to be repeated for this field. You may not always need to have something in this tab, like in our case, we leave it empty.
   ![Figure 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0gzw6xojzqnjnsrhq9ca.jpg)
7. Now, navigate to the **Settings** section after you are done with the **Fields** section. Select the **Presentation** tab and you will see several settings. In most case, it is not needed to tweak anything in the area, and you may just leave it be. This section controls the interface when you are posting or editing the content, the default is already fine.
   ![Figure 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbdv6bsi2198730uauyu.jpg)
   Once you are finish will all the **Settings** and **Fields**, save changes at the top bar. Navigate to the **Field Group** tab at the *WordPress* sidebar, and you should see the new **Field Group** you have just added.

## Create custom post type with CPT UI

1. If you have installed **Custom Post Type UI** previously, you should have seen a new entry named **CPT UI** at the *WordPress* sidebar. Hover over it and select **Add/Edit Post Types** option. You should see an interface like the figure below.
   ![Figure 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2irs1h5arwdt1bnv6bmx.jpg)
   **Post Type Slug** : the word to use for the path, if your value is *employee*, when user navigate to "https://www.yourdomain.com/employee?q=post_id", user will be able to see the full page content. This doesn't matter much as we do not want to create a dedicated page for our employee and only wanted to display it all in a page.
   
   For the **Plural Label** and **Singular Label**, enter your value respectively, for this example, *Employees* and *Employee* will be used.

2. For the **Additionals Labels** section, it is optional for you to add, and you may leave it empty as I would in this example.

3. Scroll down to the last section named **Settings**, there are some setting we have to tweak here to make it a **Private Custom Post Type**, so it doesn't generate its own dedicated page, to do this:
   
   1. Set **Publicly Queryable** to ***FALSE***.
   
   2. Set **Exclude from Search** to ***TRUE***.
   
   3. Set **Rewrite** to ***FALSE***.
   
   These three steps if important to make it private.

4. Scroll to the end of the section, at the **Supports** area, check or uncheck the feature which you need and don't need, so your editor will only have these option for you to focus on.

5. Ensured all settings are properly set and click **Add Post Type**. You should then see a new *post type* showing up at the sidebar.
   ![Figure 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7na5ckmt8d0pdcnjy20.jpg)
   To make this works with the **Advanced Custom Fields**, you have to navigate back to **Custom Field** tabs at the *WordPress* sidebar and select the **Fields Group** that you have just created, in this example, we have created *Employee*. So hover over it and click *Edit*, go to **Settings** section and change the **Post** to the **Field Group** you created, *Employee* in my example.
   ![Figure 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oe1x45c0wcwaf5uqifwt.jpg)
   Save changes and head to the *Employees* tab or any **Post Type** you have just created and *Add New*. You should see something similar to the figure below, which have an input section below.
   ![Figure 11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9d69s6uhif0s5mgfy1b.jpg)
6. Enter your content according to the input and *Publish* it! You have finished creating and posting a content on a **Custom Post Type**.

## Render the content

To output the content to your page, you need **Elementor Pro** version and some sort of premium plugins to be able to add the content with ease. Another Approach is to add a **Shortcode** to the page to render it. For example:

```php
[acf field="field_name" post_id="post_id"]
```

Replace the `"field_name"` with your *field name* you specify in the **Custom Fields**, for me, it would be *name*  or *personal_website*. Check your **Custom Field** again if you are unsure, you can find your *field_name* under the **Name** column, like the figure below outline with a red circle.
![Figure 12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wutv24ya79orf8sbz051.jpg)
So I should enter my **Shortcode** like the following in this example to display one of my employee name.

```php
[acf field="name" post_id="194"]
```

To get your `post_id`, install a plugin named [Show IDs by DraftPress](https://wordpress.org/plugins/wpsite-show-ids/), and it will display every `post_id` when you navigate to the post you have created. You should see your content being rendered if you type everything correctly.

Thanks for reading, and have a nice day :)

## Reference

- [How to create a custom post type without letting Wordpress assign a URL - WordPress Development Stack Exchange](https://wordpress.stackexchange.com/questions/297041/how-to-create-a-custom-post-type-without-letting-wordpress-assign-a-url)

- [Set posts of a custom post type to be private by default? - WordPress Development Stack Exchange](https://wordpress.stackexchange.com/questions/118970/set-posts-of-a-custom-post-type-to-be-private-by-default)

- [How To Use Dynamic Content in WordPress - Beginners Guide 2021 - YouTube](https://www.youtube.com/watch?v=UztqnNoLS7E&t)

- [Shortcode API &laquo; WordPress Codex](https://codex.wordpress.org/Shortcode_API)

- [How to add PHP Code to Elementor - WP Codeus](https://wpcodeus.com/how-to-add-php-code-to-elementor/)

- [ACF | Displaying values in your theme](https://www.advancedcustomfields.com/resources/displaying-custom-field-values-in-your-theme/)

- [ACF | Code Examples](https://www.advancedcustomfields.com/resources/code-examples/)

- [php - Shortcodes inside a shortcode - wordpress - Stack Overflow](https://stackoverflow.com/questions/4773186/shortcodes-inside-a-shortcode-wordpress)