DEV Community

WPLake
WPLake

Posted on • Originally published at wplake.org on

Display Custom Post Types and ACF fields in WordPress — WPLake

Display Custom Post Types and ACF fields in WordPress — WPLake

Custom Post Types lets you add more functionality to your website. It’s also helpful when you’re already using the standard post for something else.


Custom Post Types are a way of organizing your content, like jars in your kitchen.

About Custom Post Types

WordPress already has a built-in post type called ‘Post’. Which of course, is what many bloggers use to write their articles. As you may already know, this is one of the things that has made WordPress so popular. It’s a blogging tool on steroids, extending it with embedded content and so many other extras. With the birth of the Gutenberg editor, you now have something called blocks. Which has really been a game changer in so many ways.

Okay, so what are Custom Post Types, what can it do and why, would you even want to create more complexity in an already “feature rich” WordPress post. Well you’d be surprised.

Let’s dig in.

Plugins mentioned in this article;

Reasons to use Custom Post Types

When you’ve got posts, it’s great, but what if you’re creating a business directory. Is each post then a business or an article, what if you’ve got a news section too?

Of course you could use taxonomy to define some content categories, or even tags if you’re desperate. But ultimately the “posts” will still be posts at the end of it, saved in the same database tables. And still be listed under “Posts” in the WordPress back-end.

This isn’t actually the correct way to define different types of content. If you’ve got some blog posts and they’re in different categories, like news and notices, then it isn’t such a big deal.

Example of CPT usage

You’ve decided that you’re going to just use the built-in posts and that’s that. Then consider this, what if some content needs an extra sub headline field, or still on the business directory example. What if the “company” post already uses the ‘Featured image’ for the profile cover. Now you need an extra field for the logo, but again this logo isn’t applicable for use on other content.

It therefore quickly becomes obvious, that yes you need a way to define different types of content, and with that to assign some extra fields that’s specific to that content type.

There are ways to create a Custom Post Types (CPT) using code or other plugins, but when you’re a veteran WordPress web developer or designer. Then you probably know that every single plugin you install affects your site. So always try to reduce the number of plugins, and use only well supported plugins, which is an important aspect of WordPress speed optimization.

So with that in mind, we always try to use as few plugins as possible. In this case and most other cases we usually choose Advanced Custom Fields (ACF) for creating extra fields and since ACF v 6.1 you now have the added benefit of creating CPT’s.

Behind the scenes for Custom Post Types

There is Post Meta and Custom Post Type. Each of these play a role when it comes to custom fields.

In WordPress there are certain types of data like Posts, Images, Pages and even Users that you can create yourself. All the information is stored in a single database table that’s called ‘wp_posts’.

Therefore, when we create a Post, a Page or a User or even a WooCommerce Product. The information will be stored inside the ‘wp_posts’ table.

In the screenshot you’ll see that there a few post types, attachment, pages and acf-field. Now inside each post it has the same structure, an ID, Post Author, Date, Content, Title, Excerpt and Post Type. These attributes are all necessary and required.

Database structure

So, every entry has the same exact structure, which is defined by the structure of this table. And therefore we cannot add another column and name it what we like. That just isn’t possible, and this is where Post Meta comes in. The Post Meta is saved within a separate database called ‘wp_postmeta’. See the table below.

In this table we have ‘meta_id’, ‘post_id’, a ‘meta_key’ and a ‘meta_value’. Each entry in this table has a key and a value, and we can associate this pair to any Post ID. So in these rows of data are associations to Post ID’s, and they’re considered characteristics of the Post, or Page etc.

When you need to add a characteristic to a Post or Page or another Post Type. Then you’d need to add it in the ‘wp_postmeta’ database, and not in the ‘wp_posts’ table. That’s all you need to know about Post Meta for now.

Now let’s take a look at what Custom Post Types are.

When you look at the ‘wp_posts’ table, you’ll notice that every entry has a ‘post_type’. So we can have a Post, a Page, Attachments, Company and Images etc, they’re all considered Post Types. Where the “Company” is actually a Post Type we’ve registered in our theme.

This PHP snippet below is placed within the functions.php, file inside your theme directory.

// register a custom post type "company"
<?php
function add_cpt()
{
    $args = array(
    'labels' => array(
    'name' => 'Companies',
    'singular_name' => 'Company',
    ),
    'hierarchical' => true,
    'public' => true,
    'has_archive' => true,
    'menu-icon' => 'dashicons-building',
    'show_in_rest' => true,
    'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments',),
    'taxonomies' => array('category',),
    );
register_post_type('company', $args);

}

add_action('init','add_cpt');
Enter fullscreen mode Exit fullscreen mode

When the Custom Post Type is registered correctly, you will find the “Companies” in the admin menu.

Watch the video below for more info.

https://www.youtube.com/watch?v=fFz6OTeoiMI

Register a Custom Post Type in ACF

If you’d like to follow along, then make sure you’ve got the ACF plugin v6.1 or later installed and active.

Continue by visiting ACF -> Post Types in your Admin Back-end, here you’ll see a screen with the basic settings for a new Custom Post Type (CPT). Fill the Plural Label, Singular Label and Post Type Key. This is also the bare minimum you’d need to create a post type.

For my example, I’ll call my Plural Label as “Companies”, Singular label as “Company”, and my post key as “company”. You should feel free to create whatever you’d like here, the steps are pretty much the same.

Let’s set some advanced configuration for your new Content Type. On the same creation screen, switch on the “Advanced Configuration” toggle to show the settings. Under the ‘Supports’ heading check for various content editor features, and tick or un-tick to enable and disable them. For my case I’ve unchecked “Editor”, as I don’t plan on using it.

Switch to the Visibility tab and in the Menu icon field, add in the Dashicons class name. This isn’t critical but I recommend having some unique icon in the back-end, and if you’re building the site for a client then it looks more professional with the small extra touches. See the ‘Permissions’ tab for and turn on “Delete With User”. As in my case if a user no longer has a profile. Then I won’t allow them to have a business listed. Lastly, click “Save changes” and that’s it. You’ve just created a new Custom Post Type.

You can read more about CPT’s in the official ACF article.

Adding ACF fields to my CPT

Alright, there you have a Custom Post Type, now what?

We need some extra fields, as you know by now, we’re not just creating CPT’s for the fun of it, we’re doing it with a purpose. As a reminder the purpose is to have custom content types, for specific use cases and to keep content organized in the back-end.

Let’s create some Advanced Custom Fields (ACF) that we’ll assign to our ‘Company’ CPT.

Head over to the ACF -> Field Groups, click “Add New” and fill in the Field Group name (mine is called ‘Details’). Add a field with the “Add Field” button, select your Field Type, in my case I’m selecting “ Image “ with the field label “Logo”, with Return Format as “Image ID”.

Each “Company” really needs a Map too, so I’ll add a Google Map field, along with the User field. The intention is for a ‘company’ to get more exposure, and so that someone can find them with the map. The User field will be for associating the ‘company’ to a profile, and then also add a URL field for the company website. Lastly, in the Settings under “Location Rules” select ‘Post Type’, ‘is equal to ‘Company’ (Note: Select your CPT, if you’ve got another).

Important note: Google Maps API should be registered or the ACF Google Map field won’t work or display.

As a base set up for a ‘Company’, I’d say this is pretty solid. Any more ideas can be added later as the site grows, so let’s not add too many fields just yet. Remember to Save changes.


ACF fields with location rules for Custom Post Type.

Display a set of Posts with PHP code

Now that we’ve got all the groundwork ready, we need to display the CPT items.

Each Post Type has a template to display the associated information of a single item, but in this article we’re going to focus on displaying multiple items with their fields in a grid.

Now, you may know it’s quite a complex thing to display Posts with code, so I won’t blame you for skipping to the next section on how to display Posts with a shortcode.

For the PHP code to work, you’ll need to follow closely, and pay close attention to the field names you’ve defined when you added your fields to your Custom Post Type.

Here’s an example of a Custom Post Type for ‘Companies’, with a filter to show posts if the “Since date” year is bigger than 2010.

<?php

$queryArgs = [
    // todo use your post type here
    'post_type' => 'company',
    'post_status' => 'publish',
    // todo maximum amount of posts, use -1 to set unlimited
    'posts_per_page' => 5,
    // todo type of order
    'order' => 'DESC',
    // todo order field
    'orderby' => 'date',
    // todo use your fields
    'meta_query' => [
        [
            'key' => 'since',
            'value' => 2010,
            'compare' => '>',
            'type' => 'numeric',
        ],
    ],
];

// SQL query will be executed during this line
$query = new WP_Query($queryArgs);

// @var WP_Posts[]
$posts = $query->get_posts();

echo "<div class='companies'>";
foreach ($posts as $post) {
    $postId = $post->ID;
    $title = get_the_title($postId);
    $description = get_the_excerpt($postId);
    $since = get_field('since', $postId);
    ?>
    <div class="companies__company company">
        <h2 class="company__title"><?php
            echo $title ?></h2>
        <div class="company__description"><?php
            echo $description ?></div>
        <div class="company__about">
            <p class="company__field-label">Since:</p>
            <p class="company__field-value">
                <?php
                echo $since ?>
            </p>
        </div>
    </div>
    <?php
}
echo "</div>";
?>
Enter fullscreen mode Exit fullscreen mode

Alright, time for a summary.

When you want to display a custom set of posts you will need to a) write a query, then b) get the field data, and c) write the necessary HTML markup to display the posts. It’s all pretty flexible, and you can do great things with this method, but it also requires a lot of time and effort. And of course some PHP knowledge, so let’s rather focus on an easier way without the drawbacks.

Display a set of Posts with a shortcode

At this point you’ll need to install and activate the ACF Views plugin, because it’s really the power house of features in displaying Posts with their ACF fields without having to write the code.

Visit the ACF Views link in your admin backend, and click “Add New” to create an ACF View. We’ll use this to assign fields from our Company CPT. I’ve named my ACF View “company stub”.

Next, in the Fields section, assign the fields by selecting them from the drop down list.


Assigning the ACF fields to your ACF View.

Save your ACF View by clicking ‘Publish’.

We’re done with assigning the fields at this stage, you can edit your ACF View at any time, to add or remove fields. (Note: we’re not copying the ACF Views shortcode, we’re assigning it to our ACF Card)

Creating an ACF Card

Visit the ACF Cards and click “Add New”, name your card, in my case I’ve named it “Company list”, scroll down and assign your ACF View created earlier. This View will be used to display your Post items. Now switch to the ‘Filters’ tab and for Post Type, choose ‘Company’ or your CPT name, next, in the ‘Sort’ tab, select Title and keep “Ascending” selected for Sort order.

Click “Publish” to save and publish your ACF Card. Copy the shortcode to clipboard, we’ll paste it on our page in a minute.

Finally it’s time to create a page where you’ll display the list of posts for Company CPT.

Visit the “Pages” list and “Add New” page, call it whatever you’d like. But remember to make it clear and user friendly. I’ve kept mine simple for clarity, so just “Companies”.

If you’re using the Gutenberg editor, then add a ‘shortcode’ block, paste your ACF Card shortcode from earlier, otherwise paste your shortcode anywhere in the content. Click “Publish” or “Save draft”. We’ll come back to this page in a bit.

Fill the fields

Did we forget something?

Yes, yes we did, we have to create some ‘company’ posts, at least some dummy ‘company’ items to test if everything is working as expected.

Head over to “Companies” in the admin list and add posts, the same way you’d usually do when creating Blog posts.

When you add your first ‘Company’ post, the first thing you would notice is that it looks like a normal post edit screen, but with the extra ACF fields that were added.

Once you’ve created some ‘Company’ posts, go back to the Pages list, find your page (the page where you pasted the ACF Cards shortcode) and view it to see the results. You should have a list of posts with the fields you’ve filled displayed.

All you have to do now is add in some styles with CSS. So, go back to your ACF Views item, switch to the ‘Advanced tab” and add your styles in the CSS code field.


A set of ‘company’ custom post types displayed in a grid.

Create a list or grid of posts

To create a grid of custom post type items, like above, you could use the following CSS, replacing the tags with your field names (if needed);

/* style the cpt items, paste in ACF Views item, in CSS code field */
#view {
 width: 30%;
 border-radius: 24px;
 border: 1px solid #f4f4f4;
 padding: 20px;
 margin-bottom: 30px;
 margin-right: 20px;
}

.acf-view__logo img {
 max-height: 40px;
 position: absolute;
 margin-top: 10px;
}

.acf-view__post_title_link {
  font-size: 24px;
  padding-top: 10px;
}

.acf-view__thumbnail_id img {
 width: 100%;
}

/* show card items in one row, paste in ACF Cards item, in CSS code field */
#card__items {
 display: flex;
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, you could opt for a easier, more responsive route, especially if you’re still learning CSS. Visit your ACF Card item, switch to the ‘Layout’ tab.

This tab enables you to add rules, for mobile and other desktop screen sizes. Then it adds the CSS into the CSS code field in the ‘Advanced’ tab. It has options for different types of layouts, like “Row”, “Column” or “Grid”, with easy to define gap size and amount of columns for grid. In other words, you could have 3 per row for desktop, 5 in a row for larger screens, and then only 2 in a row for mobile, making sure it always looks neat and uncluttered on the screen.

Furthermore, if you’d like to show “Company” items, and there are some special behavior that you need to include, like having “Featured companies” which show at the top of the list, or ‘companies’ with different tiers, then you could filter by those field meta. Just include an extra section on your page (or Gutenberg block) and so forth, following a similar approach as below, where you filter by meta or taxonomy depending on your requirements.

Let’s see where you could add these filters.

Sort and Filter by Taxonomy or ACF field meta

When using ACF Views Pro, you get access to the Taxonomy Filters and Meta Filters, where you can add rules to filter by a taxonomy query, and also to add rules for filtering by a fields’ meta. In other words, if you have ‘company’ CPT items, and they have “Industry” categories, you could have a page to display only companies for a specific industry category.

Powerful meta filters allow you to do a bit more. Let’s take an example, you have ‘company’ CPT items and you’d like to show all items that have the same owner (User), then you could use $posts$.user rule.

Final thoughts

In this article we’ve shown you how to register new Content Post Types, and how to add extra ACF fields and finally, how to display a list or grid of posts, with their ACF fields on a page.

We hope this article is useful to you and that you’ll be creating more post grids and blocks of content with different CPT items for different purposes.

…and remember the main rule is to have fun, and to use as few plugins as possible.

Originally published at https://wplake.org on June 7, 2023.

Top comments (0)