Skip to content

Instantly share code, notes, and snippets.

@gemmadlou
Last active October 26, 2016 05:16
Show Gist options
  • Select an option

  • Save gemmadlou/4d38a14212bbc22f66fa3db1dbf490b5 to your computer and use it in GitHub Desktop.

Select an option

Save gemmadlou/4d38a14212bbc22f66fa3db1dbf490b5 to your computer and use it in GitHub Desktop.
Implementing MVC In Wordpress - Nested Views

Attempting MVC In Wordpress

The classes would either be included in the functions.php or namespaced and dynamically included.

Then the View Class would be called directly in a typical wordpress page.

Any nested views would be handled by calling the View Class inside.

I'm not sure if this is an anti-pattern, but it allows componentization of internal views. Each view will manage it's own data. Therefore, a super view class can be avoided.

Test here: http://phpfiddle.org/

<?php
// Uses a Model as data - not just objects
class UserViewModel {
private $displayName;
public function __construct($displayname) {
$this->displayName = $displayname;
}
public function getDisplayName() {
return $this->displayName;
}
}
class GetUserViewService {
public static function query($id) {
return new UserViewModel('Eric Banner');
}
}
interface ViewInterface {
public function action();
public function render();
}
class BaseView {
private $data;
public function __construct() {
$this->action();
$this->render($this->data);
}
}
class UserPageView extends BaseView implements ViewInterface {
public function __construct() {
parent::__construct();
}
public function action() {
$this->data = GetUserViewService::query(122);
}
public function render() {
?>
<?php echo $this->data->getDisplayName(); ?>
<?php
new SocialIconView();
}
}
class SocialIconView extends BaseView implements ViewInterface {
public function __contruct() {
parent::__construct();
}
public function action() {
$this->data = [
'Facebook',
'Twitter',
'Instagram'
];
}
// Would be an included file - so it's seperate - Model not used but preferably it should be
public function render() {
?>
<ul>
<?php foreach ($this->data as $data) { ?>
<li><?php echo $data; ?></li>
<?php } ?>
</ul>
<?php
}
}
new UserPageView();
?>
<?php
class UserViewModel {
private $displayName;
public function __construct($displayname) {
$this->displayName = $displayname;
}
public function getDisplayName() {
return $this->displayName;
}
}
class GetUserViewService {
public static function query($id) {
return new UserViewModel('Eric Banner');
}
}
interface ViewInterface {
public function render();
}
class BaseView {
private $data;
public function __construct() {
$this->action();
$this->render($this->data);
}
}
class UserPageView extends BaseView implements ViewInterface {
public function __construct($id) {
$this->data = GetUserViewService::query($id);
$this->render();
}
public function render() {
?>
<?php echo $this->data->getDisplayName(); ?>
<?php
new SocialIconView();
}
}
class SocialIconsViewModel {
private $icons = [
'Facebook',
'Twitter',
'Instagram'
];
public function __construct() {
}
public function getIcons() {
return $this->icons;
}
}
class SocialIconView extends BaseView implements ViewInterface {
public function __contruct() {
parent::__construct();
}
public function action() {
$this->data = new SocialIconsViewModel();
}
public function render() {
?>
<ul>
<?php foreach ($this->data->getIcons() as $data) { ?>
<li><?php echo $data; ?></li>
<?php } ?>
</ul>
<?php
}
}
class CardViewModel {
private $title;
private $excerpt;
public function __construct($title, $excerpt) {
$this->title = $title;
$this->excerpt = $excerpt;
}
public function getTitle() {
return $this->title;
}
public function getExcerpt() {
return $this->excerpt;
}
}
class GetCardViewService {
public static function query($id) {
// Pretend to get data based on $id
return new CardViewModel('Hello World','This is your first post.');
}
}
class CardView extends BaseView implements ViewInterface {
public function __construct($post_id) {
$this->data = GetCardViewService::query($post_id);
$this->render();
}
public function render() {
?>
<h2><?php echo $this->data->getTitle(); ?></h2>
<p><?php echo $this->data->getExcerpt(); ?></p>
<?php
}
}
class CardLayoutViewModel {
private $cards = [];
public function __construct() {}
public function addCard($card) {
$this->cards[] = $card;
}
public function getCards() {
return $this->cards;
}
}
class GetCardLayoutService {
public static function query($post_type) {
// Pretend you're using parameters to get data
$cardlayout = new CardLayoutViewModel();
$cardlayout->addCard(new CardViewModel('Hello World','This is your first post.'));
$cardlayout->addCard(new CardViewModel('Super Man Is Here','This is your second post.'));
return $cardlayout;
}
}
class CardLayoutView extends BaseView implements ViewInterface {
public function __construct($post_type) {
$this->data = GetCardLayoutService::query($post_type);
$this->render();
}
public function render() {
?>
<table>
<?php foreach ($this->data->getCards() as $card) { ?>
<tr>
<td><?php echo $card->getTitle(); ?></td>
<td><?php echo $card->getExcerpt(); ?></td>
</tr>
<?php } ?>
</table>
<?php
}
}
// page-user.php
new UserPageView(111);
new CardView(222);
new CardLayoutView('posts');
?>
<?php
// Instead of having 1 query or service, or have 2 services. Having 1 may be better for performance.
// However, proof of concept that having a list view and a nested view can work
class CardViewModel {
private $title;
private $excerpt;
public function __construct($title, $excerpt) {
$this->title = $title;
$this->excerpt = $excerpt;
}
public function getTitle() {
return $this->title;
}
public function getExcerpt() {
return $this->excerpt;
}
}
class GetCardViewService {
public static function query($id) {
// Pretend to get data based on $id
$data = [
'111' => [
'title' =>'Hello World',
'excerpt'=> 'Some content'
],
'222' => [
'title' =>'Hello World 2',
'excerpt' => 'Some content 2'
]
];
return new CardViewModel($data[$id]['title'],$data[$id]['excerpt']);
}
}
class CardView extends BaseView implements ViewInterface {
public function __construct($post_id) {
$this->data = GetCardViewService::query($post_id);
$this->render();
}
public function render() {
?>
<tr>
<td><?php echo $this->data->getTitle(); ?></td>
<td><?php echo $this->data->getExcerpt(); ?></td>
</tr>
<?php
}
}
class CardLayoutViewModel {
private $cardIds = [];
public function __construct() {}
public function addCardId($id) {
$this->cardIds[] = $id;
}
public function getCardIds() {
return $this->cardIds;
}
}
class GetCardLayoutService {
public static function query($post_type) {
// Pretend you're using parameters to get data
$cardlayout = new CardLayoutViewModel();
$cardlayout->addCardId(111);
$cardlayout->addCardId(222);
return $cardlayout;
}
}
class CardLayoutView extends BaseView implements ViewInterface {
public function __construct($post_type) {
$this->data = GetCardLayoutService::query($post_type);
$this->render();
}
public function render() {
?>
<table>
<?php foreach ($this->data->getCardIds() as $id) {
new CardView($id);
} ?>
</table>
<?php
}
}
new CardLayoutView('posts');
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment