Skip to content

Component Model

alex_prokopenko edited this page Jan 17, 2018 · 1 revision

Models are used to get data, run query with different parameters, etc. To sum up they used to separate application Data layer from View layer.

We recommend to keep Models small and group data functions in Models by such criteria:

  • The page, where these data queries are used (example: Homepage).
  • The section of the site (example: Testimonials - can have methods, which are required in all blocks all over the site).

Models help to keep templates clean from business logic and data queries.

Example: We have list of partners on the Homepage (or list of Team members). To not overload our template code with writing WP_Query call - we move it to a separate object called Model.

Model classes have to extend Framework base Model class:

class MyModel extends \JustCoded\ThemeFramework\Object\Model {}

Base Model class defines magic __get(), __set() methods, which allow to have aliases for methods to be used as properties.

Let's check an example of whole Model class:

<?php
namespace Boilerplate\Theme\Models;

use JustCoded\WP\Framework\Objects\Model;
use Boilerplate\Theme\Post_Type\Partner;

class Homepage extends Model {
	/**
	 * Get partners query to be used in home views inside the loop
	 *
	 * @return \WP_Query  query object to be used inside the loop
	 */
	public function get_partners() {
		return $this->wp_query( array(
			'post_type'      => Partner::$ID,
			'post_status'    => Partner::STATUS_PUBLISH,
			'order'          => Partner::SORT_DESC,
			'orderby'        => Partner::ORDERBY_DATE,
			'posts_per_page' => 4,
		), __METHOD__ );
	}

}

Inside the template we create an object of this class and then can use property alias $model->partners to get access to the created query:

<?php
/* @var \JustCoded\WP\Framework\Web\View $this */

use Boilerplate\Theme\Models\Homepage;

$this->extends( 'layouts/main' );
$model = new Homepage();
?>

// ...

<?php while ( $model->partners->have_posts() ) : $model->partners->the_post(); ?>
	<?php $this->include( 'page/_front-hero' ); ?>
<?php endwhile; ?>

// ...

WP_Query inside Models

There are 2 special methods to run WP_Query inside Models:

  • wp_query($params, __METHOD__) used to create WP_Query object for simple queries without pagination. It also cache this query in parent Model class.
  • archive_query($params, __METHOD__) used to create WP_Query with pagination support. Useful if you use static page as Custom Post Type archive.

Example

<?php
namespace Boilerplate\Theme\Models;

use Boilerplate\Theme\Post_Type\Employee;

class Employees extends \JustCoded\WP\Framework\Objects\Model {
	/**
	 * Get featured employees for sidebar box
	 *
	 * @return \WP_Query
	 */
	public function get_featured() {
		return $this->wp_query( array(
			'post_type'      => Employee::$ID,
			'post_status'    => Employee::STATUS_PUBLISH,
			'order'          => Employee::SORT_DESC,
			'orderby'        => Employee::ORDERBY_DATE,
			'tag'            => 'featured',
			'posts_per_page' => 4,
		), __METHOD__ );
	}

	/**
	 * Get archive employees query, whic
	 *
	 * @return \WP_Query
	 */
	public function get_archive() {
		return $this->archive_query( array(
			'post_type'     => Employee::$ID,
			'post_status'   => Employee::STATUS_PUBLISH,
			'order'         => Employee::SORT_ASC,
			'orderby'       => Employee::ORDERBY_DATE,
		), __METHOD__ );
	}
}