/IteratorPresenter.php Secret
Created
December 6, 2012 23:31
Star
You must be signed in to star a gist
Using a "real ViewModel" with Mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"require": { | |
"mustache/mustache": "*" | |
}, | |
"autoload": { | |
"classmap": ["IteratorPresenter.php", "PostViewModel.php"] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require 'vendor/autoload.php'; | |
$mustache = new Mustache_Engine(array( | |
'loader' => new Mustache_Loader_FilesystemLoader(__DIR__), | |
)); | |
// if this was real, you'd gather up some datas, but this'll do for us ... | |
$title = 'Hello World'; | |
$createdAt = new DateTime('yesterday'); | |
$tags = array('Lorem', 'Ipsum', 'Dolor'); | |
$content = <<<EOS | |
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. | |
Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum. | |
Massa justo sit amet risus. Sed posuere consectetur est at lobortis. | |
EOS; | |
// now prepare your view model | |
$viewModel = new PostViewModel($title, $content, $createdAt, $tags); | |
// you prolly want to do more with this than just echo, but here it is: | |
echo $mustache->render('post', $viewModel); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class IteratorPresenter implements IteratorAggregate | |
{ | |
private $values; | |
public function __construct($values) | |
{ | |
if (!is_array($values) && !$values instanceof Traversable) { | |
throw new InvalidArgumentException('IteratorPresenter requires an array or Traversable object'); | |
} | |
$this->values = $values; | |
} | |
public function getIterator() | |
{ | |
$values = array(); | |
foreach ($this->values as $key => $val) { | |
$values[$key] = array( | |
'key' => $key, | |
'value' => $val, | |
'first' => false, | |
'last' => false, | |
); | |
} | |
$keys = array_keys($values); | |
if (!empty($keys)) { | |
$values[reset($keys)]['first'] = true; | |
$values[end($keys)]['last'] = true; | |
} | |
return new ArrayIterator($values); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<article> | |
<h1>{{ title }}</h1> | |
<section class="content"> | |
{{{ content }}} | |
</section> | |
<aside class="meta"> | |
Published on <time data-timestamp="{{ timestamp }}">{{ createdAt }}</time>. | |
{{# hasTags }} | |
Tagged as: | |
{{# tags }} | |
<a href="/tag/{{ value }}">{{ value }}</a>{{^ last }}, {{/ last }} | |
{{/ tags }} | |
{{/ hasTags }} | |
</aside> | |
</article> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class PostViewModel | |
{ | |
private $title; | |
private $rawContent; | |
private $content; | |
private $tags; | |
// Our constructor takes property primitives. In Real Life, this would most likely | |
// take a domain model or two, e.g.: | |
// | |
// public function __construct(BlogPost $post) ... | |
// | |
// ... but that's beyond the scope of this gist :) | |
public function __construct($title, $content, DateTime $createdAt, array $tags) | |
{ | |
$this->title = $title; | |
$this->rawContent = $content; | |
$this->createdAt = $createdAt; | |
$this->tags = $tags; | |
} | |
public function content() | |
{ | |
if (!isset($this->content)) { | |
// in real life this would be Markdown processing, or something way more | |
// awesome than nl2br :) | |
$this->content = nl2br($this->rawContent); | |
} | |
return $this->content; | |
} | |
public function title() | |
{ | |
return empty($this->title) ? 'Untitled' : $this->title; | |
} | |
public function timestamp() | |
{ | |
return $this->createdAt->getTimestamp(); | |
} | |
public function createdAt() | |
{ | |
return $this->createdAt->format("F j, Y, g:i a"); | |
} | |
public function hasTags() | |
{ | |
return !empty($this->tags); | |
} | |
public function tags() | |
{ | |
return new IteratorPresenter($this->tags); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment