Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Ahondev/portfolio-v2/llms.txt

Use this file to discover all available pages before exploring further.

WP SSR Framework replaces the usual tangle of register_post_type(), register_taxonomy(), and ACF field group calls with a single fluent builder: PostType::create(). One chain of method calls registers the post type in WordPress, wires up the ACF Extended field group, generates the EloquentCPT model class, and exposes a type-safe query interface — all without touching the database or the WordPress admin.

Defining a Post Type

Post types are defined in PHP files under configuration/posts/. Each file is included automatically when the framework boots.

PostType::create()

PostType::create(
    string $slug,
    string $title,
    string $title_plural,
    string $url_rewrite,
    string $icon,
    bool   $has_seo,
    string $class_name = 'undefined'
): PostType
slug
string
required
The WordPress post type slug (e.g. article, service). Must be unique — calling create() on an already-registered slug triggers wp_die().
title
string
required
Singular label shown in the WordPress admin menu.
title_plural
string
required
Plural label used as the post type’s label argument.
url_rewrite
string
required
URL slug used for the WordPress rewrite rule (e.g. blog, services). This value should match the base path registered in your web routes.
icon
string
required
Dashicons suffix without the dashicons- prefix (e.g. hammer, art, welcome-write-blog).
has_seo
bool
required
When true, the framework registers SEO meta fields (seo_title, seo_description, seo_keywords, seo_author) for this post type. These are automatically picked up by WebController::view().
class_name
string
Optional. The short class name of the auto-generated EloquentCPT model (e.g. Article). When omitted the framework uses the slug as the class name.

Chainable methods

->taxonomy()

Registers a WordPress taxonomy associated with the post type. Pass an optional $fields array to attach an ACF Extended field group scoped to the taxonomy terms.
->taxonomy(
    string  $slug,
    string  $title,
    string  $title_plural,
    string  $url_rewrite,
    bool    $show_in_rest,
    ?array  $fields = null
): PostType

->fields()

Appends ACF Extended field objects to the field group that will be registered for this post type. Use any field type from the Extended\ACF\Fields namespace.
->fields(array $fields): PostType

->make()

Finalises the definition by calling register_extended_field_group(). You must call make() at the end of every chain.
->make(): void

Real-world examples

// configuration/posts/article.php
use Ahon\WPCMS\PostType\PostType;
use Extended\ACF\Fields\Text;
use Extended\ACF\Fields\WYSIWYGEditor;

PostType::create('article', 'Article', 'Articles', 'blog', 'welcome-write-blog', true)
    ->taxonomy('category', 'Category', 'Categories', 'blog', true)
    ->fields([
        WYSIWYGEditor::make('Contenu', 'content'),
        Text::make('Temps de lecture', 'readTime'),
        Text::make('Extrait', 'excerpt'),
    ])
    ->make();

EloquentCPT — the model layer

PostType::create() registers the post type slug with EloquentManager, which auto-generates a lightweight model class in app/PostTypes/. Each generated class looks like:
// app/PostTypes/Article.php  (auto-generated, do not edit by hand)
namespace Ahon\WPCMS\App\PostTypes;

class Article extends \Ahon\WPCMS\Eloquent\EloquentCPT
{
    public static string $model = 'article';
}
The base EloquentCPT class maps all standard WP post fields plus every ACF field to typed properties automatically in its constructor via initACFFields():
// Built-in properties on every EloquentCPT instance
public int                    $id;
public string                 $type;
public string                 $title;
public string                 $content;
public string                 $excerpt;
public string|false|\WP_User  $author;
public string                 $date;
public string                 $thumbnail;
public string                 $slug;

// ACF fields are added dynamically — e.g. for Article:
// public string $readTime;
// public string $excerpt; (overwritten by ACF value if present)

toArray()

Serialize a model instance to a plain PHP array — useful for JSON encoding or passing to a view:
$article->toArray();
// Returns: ['id' => 42, 'title' => '...', 'readTime' => '5 min', ...]

Querying with QueryBuilder

Use the static query() method on any EloquentCPT subclass to start a fluent query:
EloquentCPT::query(): QueryBuilder  // called on an EloquentCPT subclass

Common query methods

MethodDescription
->all()Fetch all published posts (no limit) — shorthand for ->limit(-1)->get()
->limit(int $n)Cap results at $n posts
->offset(int $n)Skip the first $n posts
->orderBy(string $field, string $order)Order by any field; use the ASC or DESC constants
->random(int $n)Return $n posts in random order
->where(string $key, string $op, mixed $value)ACF meta query; operator can be =, !=, >, <, LIKE, etc.
->orWhere(...) / ->andWhere(...)Combine meta conditions with OR / AND relation
->taxonomy(string $taxonomy, string|array $term)Filter by taxonomy term slug
->with('taxonomy', 'category', ...)Eager-load taxonomy terms in one optimised SQL query
->search(string $query)Full-text WordPress search
->matchIds(array $ids)Fetch specific posts by ID
->matchSlugs(array $slugs)Fetch specific posts by slug
->get()Execute the query; returns an Illuminate Collection

Querying taxonomy terms

EloquentCPT::queryTerms(string $taxonomy, bool $hideEmpty = false): \Illuminate\Support\Collection
Returns an Illuminate Collection of ['id', 'name', 'slug'] maps, filtering out the default “Uncategorized” term automatically.

Usage in a controller

// Fetch all articles in a specific category, ordered newest-first
$posts = Article::query()
    ->taxonomy('category', 'tutorials')
    ->orderBy('date', DESC)
    ->with('taxonomy', 'category')
    ->all();

// Fetch the 3 most recent services for a home-page preview
$featured = Service::query()
    ->limit(3)
    ->orderBy('date', DESC)
    ->get();

// Fetch taxonomy terms for a filter UI
$categories = Article::queryTerms('category', hideEmpty: true);
->all() is a shorthand for ->limit(-1)->get(). The return value is always an Illuminate Collection, so you can chain ->map(), ->filter(), ->pluck(), etc. before passing data to a view.

Build docs developers (and LLMs) love