Typically in WordPress when you're querying posts you get WP_Post objects back. Timber have taken this a step further and return a Timber/Post object instead. This has a ton of great helper methods and properties which makes it easier and more expressive to use.
In this example $collection contains App\PostType\Product objects. That allows you to add your own methods to a product and encapsulate logic in one place.
useApp\PostTypes\Product;$collection =Product::query($wpQueryArray);foreach ($collection as $product) {echo $product->price();}
namespaceApp\PostTypes;useRareloop\Lumberjack\Post;classProductextendsPost{// ...publicfunctionprice() {// Get the price from the ACF field for this productreturnget_field('price',$this->id); }}
If collections are new to you, be sure the check out the documentation on them:
Register Custom Post Types
First, create a new file in app/PostTypes/. We recommend using singular names. For this example, lets add a Product.php file there.
You can use this boilerplate to get you started:
namespaceApp\PostTypes;useRareloop\Lumberjack\Post;classProductextendsPost{/** * Return the key used to register the post type with WordPress * First parameter of the `register_post_type` function: * https://codex.wordpress.org/Function_Reference/register_post_type * * @returnstring */publicstaticfunctiongetPostType() {return'products'; }/** * Return the config to use to register the post type with WordPress * Second parameter of the `register_post_type` function: * https://codex.wordpress.org/Function_Reference/register_post_type * * @returnarray|null */protectedstaticfunctiongetPostTypeConfig() {return ['labels'=> ['name'=>__('Products'),'singular_name'=>__('Product'),'add_new_item'=>__('Add New Product'), ],'public'=>true, ]; }}
Lumberjack will handle the registering of the post type for you. In order to do that, it requires 2 methods (documented above):
getPostType()
getPostTypeConfig()
In order for Lumberjack to register your post type, you need to add the class name to the config/posttypes.php config file.
return [/** * List all the sub-classes of Rareloop\Lumberjack\Post in your app that you wish to * automatically register with WordPress as part of the bootstrap process. */'register'=> [App\PostTypes\Product::class, ],];
And that's it! You can now start using your new Custom Post Type.
Tip: Try and avoid using ACF's get_field outside of a Post Type class where possible. This will help make your application easy to change.
$product =newProduct;// Badechoget_field('price', $product->id);// Good: The knowledge of how to get the price is encapsulated within the Product classecho $product->price();
Available Methods for Rareloop\Lumberjack\Post
Lumberjack's Post class extends Timber\Post, and adds some convenient methods for you:
useRareloop\Lumberjack\Post;useApp\PostTypes\Product;// Get all published posts, with 10 per page, ordered ascending by title$posts =Post::all(10,'title','asc');// Accepts the WP_Query args as an array. By default it will filter by published posts for the correct post type too$products =Product::query(['s'=>'Toy Car']);
Extending Post Types
The Lumberjack Post class can be extended with custom functionality at runtime (the class is "macroable"). The following example adds an acf method to the Post class that can be used to access Advanced Custom Field (ACF) field values:
useRareloop\Lumberjack\Post;// Add custom functionPost::macro('acf',function ($field) {returnget_field($field,$this->id);});// Use the functionality$post =newPost;$value = $post->acf('custom_field_name');