Posttype

Introduction

Posttype refers to the various data that is maintained in the WordPress posts table. Custom post types allow developers to easily create and manage complex content structures.

Creating posttype

By default, post types are stored inside app\Posttypes directory.

Via console command

Scaffold posttype with wp assely:make posttype command.

wp assely:make posttype Movies
Specifying slug

This will create posttype with movies slug, but you can specify it with --slug option.

wp assely:make posttype Movies --slug="movie"

Manually created class file

Make a file with the class that extends base Assely\Posttype\Posttype class.

The slug property is required. This value determines under which name your posttype will be registered and accessible.

// app/Posttypes/Movies.php

namespace App\Posttypes;

use Assely\Posttype\Posttype;

class Movies extends Posttype
{
    /**
     * Posttype slug.
     *
     * @var string
     */
    public $slug = 'movies';

    /**
     * Posttype arguments.
     *
     * @return array
     */
    public function arguments()
    {
        return [
            //
        ];
    }

    /**
     * Specify columns of the posttype posts list.
     *
     * @return \Assely\Column\Column[]
     */
    public function columns()
    {
        return [
            //
        ];
    }
}

Configuring posttype

Registering posttype

All posttypes are registered in the config/singularities.php configuration file. This file contains a posttypes array where you can add your newly created custom posttypes.

'posttypes' => [
    // ...other posttypes

    App\Posttypes\Movies::class,
],

The Arguments method

The arguments method must always return an array of post type registration parameters. You can use all of the default WordPress parameters, but there is also some "framework specific".

public function arguments()
{
    return [
        'title' => ['Bollywood Movie', 'Bollywood Movies'],
    ];
}
Parameter name Default value Description
title [] Array of titles, where the first element is singular variant, second a plural

The Columns method

The columns method allows for defining custom posttype columns which are displayed on the list of posts.

Posttypes accepts two kinds of columns: taxonomy and metabox.

public function columns()
{
    return [
        Column::taxonomy('App\Taxonomies\Genres'),
        Column::metabox('App\Metaboxes\MovieDetails', 'release_date'),
    ];
}

Using posttype

Injecting the custom posttype repository provides fluent access to its posts. However, you can also use Post facade.

Post::type('movies')->find(1);

Quering posts

Of course, once you created and registered your Posttype, you can start retrieving posts data for your views. In this section, you will learn how you can query your custom post types.

Fetching multiple posts

The all method will retrieve all of the posttype posts. This method returns an instance of Illuminate\Support\Collection, so you can easily modify results with diffrent methods.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    $movies = $movies->all();
}

Paginating posts

Before querying posts, you can declare if they have to be paginated. Use paginate method.

It requires current page number to be passed as method argument.

use App\Posttypes\Movies;

public function index(Movies $movies, $paged = 1) {
    $movies = $movies->paginate($paged)->all();
}

Retrieving single post

You can also immediately search for the single post. Pass post id or slug as the find method argument.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    // ..with post id
    $movie = $movies->find(1);

    // ..or post slug
    $movie = $movies->find('pirates-of-the-caribbean');
}
Not Found Query Exception

Sometimes you want to throw an exception when a post was not found. The findOrFail method returns the found post, but if not Assely\Database\QueryException will be thrown.

$movies->findOrFail(1);

Fetching posts with specified term

You may need to retrieve only posts with a specifed term. The withTerm method with desired Assely\Adapter\Term instance passed as the argument will return only posts which have this term.

use App\Posttypes\Movies;
use App\Taxonomy\Genre;

public function index(Movies $movies, Genre $genres) {
    $comedy = $genres->find('comedy');

    $comedyMovies = $movies->withTerm($comedy);
}

Custom query

Needs something more complex? You can use query method with an array of Query Parameters as the argument.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    $arguments = [
        'tax_query' => [
            'relation' => 'AND',
            [
                'taxonomy' => 'genre',
                'field' => 'slug',
                'terms' => ['fantasy'],
            ],
            [
                'taxonomy' => 'actor',
                'field' => 'slug',
                'terms' => ['johnny-depp'],
            ],
        ]
    ];

    $johnnyDeppFantasyMovies = $movies->query($arguments);
}

Inserting posts

Use create method with an array of properties and values for inserting new post to the database.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    $movies->create([
        'title' => 'Pirates of the Caribbean',
    ]);
}
Inserting Query Exception

The createdOrFail method will insert new post, but when an error occurs Assely\Database\QueryException will be thrown.

$movies->createOrFail([
    'title' => 'Pirates of the Caribbean',
]);

Updating posts

To update a post, you need to set new property values on retrieved Assely\Adapter\Post instance, and then call save method.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    $movie = $movies->find(1);

    $movie->title = 'Pirates of the Caribbean';

    $movie->save();
}

Deleting posts

Call destroy method on retrieved Assely\Adapter\Post instance to remove a post from the database.

use App\Posttypes\Movies;

public function index(Movies $movies) {
    $movie = $movies->find(1);

    $movie->destroy();
}

Displaying posts

You have access to the bunch of different properties. List of all you can find in adapters documentation.

<div class="movie">
    <h1>{{ $movie->title }}</h1>
    <time>{{ $movie->created_at }}</time>
    <p>{{ $movie->content }}</p>
</div>

Looping on collection of posts

Easy as pie. Just standard loop.

@foreach($movies->all as $movie)
    <a href="{{ $movie->link }}">{{ $movie->title }}</a>
@endforeach

Accessing post thumbnail

You can access post thumbnail image with thumbnail property. By default, it contains image size configured in config/images.php file. This property returns Assely\Thumbnail\Image instance with various image information.

<img src="{{ $movie->thumbnail->link }}" alt="{{ $movie->thumbnail->title }}">

You may need to display a thumbnail in different size. Use thumbnail method with thumbnail size slug as the argument.

For example, you have registered custom thumbnail size named hero, you can access it with this name.

<img src="{{ $movie->thumbnail('hero')->link }}" alt="{{ $movie->thumbnail->title }}">
Checking if post have thumbnail

Of course, before displaying image, you can check if post thumbnail is actually set.

@if($movie->hasThumbnail)
    <!-- post have thumbnail -->
@endif

Accessing post metadata

Your posts may hold various metadata. The meta method helps you retrieve this information. You only need to pass metadata key under which they are stored.

{{ $movie->meta('movie_details') }}

It returns an Illuminate\Support\Collection, so you have a flexible way to access its values.

{{ $movie->meta('movie_details')->get('release_date') }}

Retrieving post terms

Getting all terms assigned to the post

To retrieve all terms assigned to the post, you can use terms property.

@foreach($movie->terms as $term)
    <span>{{ $term->title }}</span>
@endforeach

Getting terms of specific taxonomy assigned to the post

terms method with taxonomy slug as the argument will retrieve only post terms from the specific taxonomy.

@foreach($movie->terms('genre') as $genre)
    <span>{{ $genre->title }}</span>
@endforeach

Retrieving post comments

You can also access a collection of post comments.

@foreach($movie->comments as $comment)
    <span>{{ $comment->author }}</span>
    <p>{{ $comment->content }}</p>
    <time>{{ $comment->created_at }}</time>
@endforeach