Register custom post types without Pods: a plugin you can build today

· 5 min read

Pods is a well-maintained plugin with a large feature set: custom post types, custom fields, relationships between post types, front-end templating, and an admin UI that lets non-developers add fields without touching code. A CVE disclosed this month is patched and the plugin is safe to run after updating. The disclosure is not a reason to switch.

But it is a prompt to ask the question. Most sites that installed Pods did it for one specific reason: to register a custom post type or two with a handful of fields. The relationships, the templating, the magic tag system, the admin UI for adding new fields without code changes - for many sites, none of that was ever turned on. What is running is a plugin with all of that surface, and the site is only using the five lines of it that call register_post_type.

A plugin that registers exactly the post types you use and nothing else is sixty to a hundred lines of PHP. It has no settings page, no AJAX handlers, no user-facing input, and almost no attack surface. Here is how to build one.

What one build gives you

  • Registration of named custom post types with labels, archive, and menu icon via register_post_type
  • Meta boxes for each post type with text, number, date, URL, and select fields
  • Nonce-verified meta save on save_post with sanitization per field type
  • Custom taxonomy registration via register_taxonomy when you describe the taxonomy in the prompt

What it does not do

  • A visual admin UI for adding new post types or fields without editing code
  • Relationships between post types: those need WP_Query arguments written by hand
  • Front-end templating, Pods Pages, or magic tags
  • File upload or repeater fields without additional prompt work
  • Import of Pods field configuration: you describe your CPTs and fields in the prompt yourself

Pods does these. This covers the part most sites use.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin that registers two custom post types: Portfolio and Testimonial. For Portfolio: labels Portfolio (singular) and Portfolios (plural), supports title, editor, and thumbnail, has_archive true, menu_icon dashicons-portfolio, public true. Add a meta box titled Portfolio Details with fields for Project URL (text input, meta key portfolio_project_url), Client Name (text input, meta key portfolio_client), and Completion Date (date input, meta key portfolio_completion_date). For Testimonial: labels Testimonial (singular) and Testimonials (plural), supports title and editor, has_archive false, menu_icon dashicons-format-quote, public true. Add a meta box titled Testimonial Details with fields for Client Company (text input, meta key testimonial_company) and Rating (number input 1 to 5, meta key testimonial_rating). Save all meta fields on save_post using wp_verify_nonce for security, skip autosaves, and sanitize each value with sanitize_text_field or intval as appropriate. Register post types on init. Do not use any framework or external library.

Build this pluginAbout 55 credits · the free plan includes enough for one

What Pods does, and what most sites actually use

Pods ships a visual field builder, a relationships system for linking post types to each other, a front-end Pods Pages system for custom display, and a templating language with magic tags. It also ships the core thing most people installed it for: a way to register custom post types and attach meta fields to them.

For sites that only use the second part, the rest is still there. Every feature in Pods is code that runs, and code that runs is surface area that can be audited, found vulnerable, and exploited. Switching to a smaller plugin does not mean the smaller plugin is better code. It means there is less code to audit in the first place.

What a purpose-built plugin looks like

A Steem build for this job produces a plugin that calls register_post_type on the init hook, adds meta boxes with add_meta_boxes, and saves field values on save_post with nonce verification. There is no settings page. There is no AJAX handler. Fields are defined in the plugin file itself, not in the database.

The tradeoff is direct: adding a new field or a new post type means editing the plugin. On a site where a developer handles code changes, that is not a tradeoff. On a site where a client needs to add a field from the admin without touching code, Pods remains the right tool.

Who should keep Pods

If a client or editor on your site adds or modifies fields from the admin, stay on Pods. The ability to change the data model without a code deploy is exactly what Pods is for, and nothing in this guide replaces it.

If you use Pods relationships to link post types together, the relationship queries are baked into your templates and you would need to rewrite that logic with WP_Query arguments. That may or may not be worth doing.

If you use Pods templates or magic tags anywhere in your theme, those references would break. Removing them before switching is a non-trivial project on a content-heavy site.

If none of the above applies and you are running Pods only to register a fixed set of post types with a fixed set of fields, a purpose-built plugin is a reasonable alternative.

How to migrate without losing data

Switching the registration mechanism does not touch your database. Posts remain. Meta values remain. Your custom post type slugs and field key names can stay identical to what Pods used, so existing content continues to render correctly.

The one thing to check before switching: the meta key names Pods stored your fields under. In Pods, fields are stored under the key you defined in the Pods admin. Match those key names exactly in your new plugin and the data is read seamlessly. If you are not sure what keys Pods is using, call get_post_meta on a known post ID with no key argument - it returns all meta for that post - or query wp_postmeta directly.

How to build it

Paste the prompt below into Steem, substituting your own post type names and field names. The plugin downloads as a zip and installs under Plugins > Add New > Upload Plugin.

Once active, verify each post type appears in the admin menu and that your existing posts are still visible. Then deactivate Pods. If anything breaks, reactivating Pods brings everything back - the data is untouched.

Questions

Is Pods still safe to run after the patch?
Yes. The vulnerability disclosed in August 2026 was patched and responsibly disclosed. Updating to the patched version is the straightforward response. Switching to a custom plugin is a separate decision about whether you need everything Pods ships.
Will my existing post content and meta survive the switch?
Yes. The database is not touched. Posts, taxonomies, and meta values remain exactly as they were. The only thing that changes is which plugin registers the post type. As long as the post type slug and meta key names match, existing content renders normally.
How do I find the meta key names Pods used for my fields?
The key names match the field slugs you set in the Pods admin. You can also check by calling get_post_meta on a known post ID with no key argument - it returns all meta for that post. Or query the wp_postmeta table directly: SELECT meta_key FROM wp_postmeta WHERE post_id = [your post ID].
Can I also register custom taxonomies through this plugin?
Yes. Describe the taxonomy in the prompt: its name, the post type it attaches to, whether it is hierarchical, and whether it should have an archive. Steem will add a register_taxonomy call alongside the post type registration.
What if I need to add a field after the plugin is built?
Edit the plugin file. Add the field definition to the meta box callback and add the corresponding save line in the save handler. This is the core tradeoff: Pods lets anyone add a field from the admin; a custom plugin requires a code change.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin that registers two custom post types: Portfolio and Testimonial. For Portfolio: labels Portfolio (singular) and Portfolios (plural), supports title, editor, and thumbnail, has_archive true, menu_icon dashicons-portfolio, public true. Add a meta box titled Portfolio Details with fields for Project URL (text input, meta key portfolio_project_url), Client Name (text input, meta key portfolio_client), and Completion Date (date input, meta key portfolio_completion_date). For Testimonial: labels Testimonial (singular) and Testimonials (plural), supports title and editor, has_archive false, menu_icon dashicons-format-quote, public true. Add a meta box titled Testimonial Details with fields for Client Company (text input, meta key testimonial_company) and Rating (number input 1 to 5, meta key testimonial_rating). Save all meta fields on save_post using wp_verify_nonce for security, skip autosaves, and sanitize each value with sanitize_text_field or intval as appropriate. Register post types on init. Do not use any framework or external library.

Build this pluginAbout 55 credits · the free plan includes enough for one

Read next

Other plugins you can build this way

Each loads into the composer, ready to edit.