Skip to content
BeoHosting
BeoHosting
WordPress

Guide to WordPress Custom Post Types

BeoHosting Team··10 min read read
Guide to WordPress Custom Post Types

What are custom post types

The WordPress platform by default ships with two content types - posts (blog articles) and pages. However, most sites have content that doesn't belong to either of these types. Portfolio projects, products, reviews, events, real estate listings, recipes, or team members are examples of content that requires its own structure and display. Custom post types let you create new content types with their own fields, taxonomies, and templates.

Custom post types are a fundamental concept in WordPress development that turns WordPress from a blogging platform into a complete CMS (Content Management System). Every WordPress plugin that adds a new content type such as WooCommerce products, The Events Calendar events, or Portfolio plugins uses custom post types under the hood. Understanding CPTs gives you full control over the content structure on your site.

Registering a custom post type

The register_post_type function

A custom post type is registered using the WordPress function register_post_type called inside the init hook. The function takes two arguments - a slug which is the internal content type identifier and an array of arguments that define the behavior and appearance in the admin panel. The slug should be singular, lowercase, with no spaces, and a maximum of 20 characters. For example for portfolio projects the slug would be project, for real estate property, for recipes recipe.

Key arguments

  • labels: An array of labels WordPress uses in the admin interface including name for plural, singular_name for singular, add_new for the add button, edit_item for the edit page title, and search_items for search.
  • public: Whether the content type is publicly available on the frontend. Set to true for content visitors should see.
  • has_archive: Whether the content type has an archive page that displays all items, similar to the blog page for posts.
  • supports: Which WordPress features are available for this content type including title, editor, thumbnail, excerpt, custom-fields, comments, and revisions.
  • menu_icon: A Dashicons icon displayed in the admin sidebar. WordPress comes with 300+ icons for different purposes.
  • rewrite: Defines the URL structure for this content type. For example slug portfolio creates URLs like yoursite.com/portfolio/project-name.
  • show_in_rest: Enables Gutenberg editor and REST API access. Set to true for modern WordPress sites.

Advanced Custom Fields (ACF)

Why use ACF

WordPress custom fields are the basic mechanism for adding extra data to content but the native interface is impractical. The Advanced Custom Fields plugin transforms the content creation experience by adding intuitive fields like text input, textarea, image picker, datepicker, Google Maps field, relationship fields, and much more. ACF is the de facto standard in WordPress development with over 2 million active installations and is used by agencies worldwide.

Field types

ACF offers over 30 field types organized into categories. Basic fields include text, textarea, number, email, URL, and password. Choice fields are select, checkbox, radio button, button group, and true/false. Content fields are image, file, WYSIWYG editor, oEmbed for video, and gallery. Relational fields are link, post object, page link, relationship, and taxonomy. Layout fields are group, repeater for repeating sections, flexible content for modular layouts, and clone. The repeater field is particularly powerful because it allows creating repeating structures like a list of team members, sections with icons, or a specifications table.

Displaying ACF fields

ACF provides simple PHP functions for displaying field values in themes. The get_field function returns the field value while the_field directly outputs the value. For images, get_field returns an array with URL, width, height, and alt text. For repeater fields, use have_rows and the_row in a while loop to iterate through all rows. For flexible content, use get_row_layout to determine which layout is in play and display the corresponding template. ACF documentation is extremely detailed with examples for every field type.

Custom taxonomies

What taxonomies are

Taxonomies are systems for content classification. WordPress by default has two taxonomies - categories which are hierarchical and tags which are flat. For custom post types, custom taxonomies are usually needed. For example, portfolio projects may have a project type taxonomy with values like web design, branding, and photography. Real estate may have taxonomies for location, property type, and price range. Recipes may have cuisine, dish type, and difficulty level.

Registering taxonomies

The register_taxonomy function is called inside the init hook similar to register_post_type. It takes three arguments - the taxonomy slug, an array of post types it applies to, and an array of arguments. The hierarchical argument determines whether the taxonomy works like categories with a parent-child relationship or like tags with a flat structure. Labels define how the taxonomy displays in the admin panel. The rewrite argument controls the URL structure for taxonomy archive pages.

Hierarchical vs flat taxonomies

Hierarchical taxonomies display as a checkbox list in the admin panel with the ability to create parent and child terms. Use them for classifications with a clear structure like locations where the US has subcategories New York, Los Angeles, and Chicago. Flat taxonomies display as a tag input field where you type terms separated by commas. Use them for flexible labels like technologies, skills, or characteristics where there's no hierarchical relationship.

Template files for custom post types

WordPress template hierarchy

WordPress uses a specific hierarchy to determine which template file will be used for displaying content. For a custom post type with slug project, WordPress looks for files in the following order. For single items it looks for single-project.php then single.php then singular.php then index.php. For the archive page it looks for archive-project.php then archive.php then index.php. Create specific template files for your CPT to have full control over the display.

Single template

The single template displays one item of your custom post type. For example single-project.php for a portfolio project displays the project title, featured image, description, ACF fields like client, date, project URL, and image gallery. Use the WordPress loop the_loop to access post data and ACF functions for custom fields. Add navigation between projects with previous_post_link and next_post_link and a related projects section based on taxonomy.

Archive template

The archive template displays a list of all items with filtering by taxonomy. For example archive-project.php displays a grid of portfolio projects with thumbnail, title, category, and short description. Add filter buttons for taxonomies so visitors can filter projects by type. Pagination enables navigation through a large number of items. For advanced display, use WP_Query with custom arguments for sorting, filtering, and grouping items.

WP_Query for custom post types

Custom queries

The WP_Query class enables creating custom queries for fetching custom post type items with specific criteria. The post_type argument defines which content type you're fetching. posts_per_page controls the number of results. orderby and order define sorting by date, title, menu_order, or meta value. tax_query filters by taxonomy with the ability to combine multiple taxonomies using AND or OR operators. meta_query filters by custom field values with operators like equals, greater than, less than, LIKE, and BETWEEN.

Query examples

To display the last 6 portfolio projects from the web design category sorted by date, use WP_Query with arguments post_type project, posts_per_page 6, tax_query with taxonomy project_type and term web-design. To display real estate listings with a price between 50,000 and 100,000 dollars, use meta_query with key price, NUMERIC type, and BETWEEN operator. Always reset the global post object with wp_reset_postdata after custom queries so you don't break the main WordPress loop.

REST API and Gutenberg

REST API access

With the show_in_rest argument set to true, your custom post type automatically gets a REST API endpoint at yoursite.com/wp-json/wp/v2/slug. This enables fetching, creating, updating, and deleting items via API calls, which is the foundation for headless WordPress access and JavaScript frontends. ACF fields can be exposed in the REST API using the ACF to REST API plugin or by manually registering fields with the register_rest_field function.

Gutenberg blocks

With show_in_rest enabled, your CPT uses the Gutenberg editor instead of the classic editor. You can create custom Gutenberg blocks specific to your content type using ACF Blocks which enables creating blocks with PHP templates and ACF fields without React knowledge. For example, for a portfolio you can create a block that displays a grid of selected projects, or for recipes a block that formats the ingredient list and preparation steps with custom styling.

Best practices for custom post types

Naming and organization

Use a prefix for your CPT slug to avoid conflicts with other plugins and WordPress updates. For example, instead of project use myplugin_project. Group registration of CPTs and taxonomies in a separate class or file for easier maintenance. Use constants for slugs to avoid typo errors. Document every CPT with a description of its purpose, list of ACF fields, and taxonomies.

Performance

Every custom post type adds database queries so avoid creating too many CPTs when taxonomies can achieve the same goal. For example, instead of separate CPTs for blog, news, and tutorials, use standard posts with categories. ACF fields are stored as post meta in the database - for fields frequently used in queries, consider creating a custom table for better performance. Cache complex WP_Query queries using the transient API to reduce database load. On our WordPress hosting solutions we have an environment optimized for sites with custom post types and advanced queries with enough PHP memory and fast SSD disks for a responsive admin experience.

Conclusion

Custom post types transform WordPress from a blog platform into a powerful CMS capable of managing any type of content. The combination of the register_post_type function for creating content types, ACF for custom fields, custom taxonomies for classification, and template files for display gives you full control over content structure and presentation. This knowledge is the foundation of professional WordPress development (start with our guide) and opens possibilities for creating complex sites like portfolio presentations, product catalogs, directories, and business applications.

BeoHosting Team

10+ years of experience — Web hosting and infrastructure specialists

  • Web Hosting
  • WordPress Hosting
  • VPS
  • Dedicated Serveri
  • Domeni
  • SSL
  • cPanel
  • LiteSpeed
  • Linux administracija
  • DNS

Last updated: