Skip to content

getting started

Polmonite edited this page Sep 21, 2019 · 1 revision

Getting Started

Let's see a quick example; imagine that we are creating a custom theme and we are inside the single-book.php template. We want to have all the classic data exposed by a WP_Post, like the post_title, ID, etc., and that we want to place it inside a PHP associative array. In Malini we could simply do:

$content = malini_post()
    ->decorate('post')
    ->toArray();

If we var_dumped the $content variable, it would look something like:

array (
  'id' => 62,
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'filtered_content' => '',
  'status' => 'publish',
  'excerpt' => 'The Post Excerpt.',
  'created_at' => '2019-08-19 18:24:52',
  'slug' => 'the-post-title',
  'updated_at' => '2019-08-19 18:46:19',
  'parent_id' => 0,
  'order' => 0,
  'posttype' => 'post',
  'permalink' => 'http://www.malini.test/my-category/the-post-title/',
)

Note that the keys have been normalized by default.

This is what happened:

  • malini_post(): this method retrieves the current post (get_post()) and wraps it in a Malini\Post; it is also possibile to call the malini_post with a valid numeric ID or passing an instance of WP_Post;
  • ->decorate('post'): this method applies the post decorator to the Malini\Post; this decorates the Malini\Post with all the default data usually found in a WP_Post and maps its keys with a normalized version of the sames keys;
  • ->toArray();: transform the decorated entity in an array; there are also other useful and similar method, like toObject and toJson.

Let's say that we only want to expose the title, content, excerpt and created_at attributes; it would look something like this:

$content = malini_post()
    ->decorate('post', [
        'filter' => [ 'title', 'content', 'excerpt', 'created_at' ]
    ])
    ->toArray();

The var_dumped $content variable would then look like:

array (
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'excerpt' => 'The Post Excerpt.',
  'created_at' => '2019-08-19 18:24:52',
)

The post decorator is only one of the available decorators; if we wanted the post categories, we could use the categories decorator, like this:

$content = malini_post()
    ->decorate('post', [
        'filter' => [ 'title', 'content', 'excerpt', 'created_at' ]
    ])
    ->decorate('categories')
    ->toArray();

Obtaining:

array (
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'excerpt' => 'The Post Excerpt.',
  'created_at' => '2019-08-19 18:24:52',
  'categories' => 
  array (
    0 => 
    array (
      'term_id' => 5,
      'name' => 'Example Category 1',
      'slug' => 'example-category-1',
      'term_group' => 0,
      'term_taxonomy_id' => 5,
      'taxonomy' => 'category',
      'description' => 'A valid description of category 1',
      'parent' => 0,
      'count' => 2,
      'filter' => 'raw',
    ),
    1 => 
    array (
      'term_id' => 1,
      'name' => 'Example Category 2',
      'slug' => 'example-category-2',
      'term_group' => 0,
      'term_taxonomy_id' => 1,
      'description' => 'A valid description of category 2',
      'description' => '',
      'parent' => 0,
      'count' => 2,
      'filter' => 'raw',
    ),
  ),
)

Now: the categories property has a little too much information; let's see how to filter data out. The decorate method accepts as a second argument an $option array and every decorator can have different available options. The job of a decorator here is to extend the Malini\Post with new attributes, so one option that is usually available is filter, which gives the ability to specify the attributes we want to show (like we did before). The filter option can also specify nested rules; for example:

$content = malini_post()
    ->decorate('post', [
        'filter' => [ 'title', 'content', 'excerpt', 'created_at' ]
    ])
    ->decorate('categories', [
      'filter' => [
        'categories' => [
          '*' => [
            'term_id',
            'name',
            'slug'
          ]
        ]
      ]
    ])
    ->toArray();

This way we obtain:

array (
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'excerpt' => 'The Post Excerpt.',
  'created_at' => '2019-08-19 18:24:52',
  'categories' => 
  array (
    0 => 
    array (
      'term_id' => 5,
      'name' => 'Example Category 1',
      'slug' => 'example-category-1',
    ),
    1 => 
    array (
      'term_id' => 1,
      'name' => 'Example Category 2',
      'slug' => 'example-category-2',
    ),
  ),
)

Now: let's say we want to show title, content and excerpt, but we don't want to use the whole post decorator; we could end up with something like:

$content = malini_post()
    ->addAttributes([
      'title' => '@base:post_title',
      'content' => '@base:post_content'
      'excerpt' => '@base:post_excerpt'
    ])
    ->toArray();

Result:

array (
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'excerpt' => 'The Post Excerpt.',
)

This is actually how the post decorator is implemented; addAttributes gives us a way to define new attribute and how to retrieve them, through what's called an Accessor. Accessors are defined throuh a string using this syntax:

@{accessor_type}:{arg_1},...,{arg_2}

So the code above define three attributes, that use the BaseAccessor, which retrieves a property of the underlying WP_Post. By default the BaseAccessor is used, so the code above can be semplified as this:

$content = malini_post()
    ->addAttributes([
      'title' => 'post_title',
      'content' => 'post_content',
      'excerpt' => 'post_excerpt'
    ])
    ->toArray();

There are other accessors available; for example, let's say that our post has a post_meta called author_nickname; we could show it like this:

$content = malini_post()
    ->addAttributes([
      'title' => 'post_title',
      'content' => 'post_content',
      'excerpt' => 'post_excerpt',
      'author_nickname' = >'@meta:author_nickname'
    ])
    ->toArray();

The MetaAccessor (@meta) retrieves the specified meta_key (author_nickname), so:

array (
  'title' => 'The Post Title.',
  'content' => 'The Post Content.   ',
  'excerpt' => 'The Post Excerpt.',
  'author_nickname' => 'Simon Pegg',
)

Last but not least, let's say we want to do some simple formatting, like trimming the content, snake_casing the title or formatting the created_at date. Malini exposes a list of simple function that can be assigned to attributes, called filters. For example:

$content = malini_post()
    ->addAttributes([
      'title' => 'post_title',
      'content' => 'post_content',
      'excerpt' => 'post_excerpt',
      'author_nickname' = >'@meta:author_nickname',
      'created_at' => 'post_date'
    ])
    ->addFilters([
        'title' => 'snakecase',
        'content' => 'trim|uppercase',
        'created_at' => 'format_date:Y-m-d'
    ])
    ->toArray();

As you can see with the case of content, filters can be piped. Gives us:

array (
  'title' => 'the_post_title',
  'content' => 'THE POST CONTENT.',
  'excerpt' => 'The Post Excerpt.',
  'author_nickname' => 'Simon Pegg',
  'created_at' => '2019-08-19',
)

These are some basic examples: different accessors and different decorators have different options. Also you can extend Malini with your own accessors, decorators and filters; find out how here.

Other

Extend Malini

  • Create your own Accessor
  • Create your own Decorator
  • Available Extensions
    • Malini\Aeria
    • Malini\YOAST
    • Malini\ACF
Clone this wiki locally