aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Enderlin <ivan.enderlin@hoa-project.net>2014-01-25 20:46:35 +0100
committerIvan Enderlin <ivan.enderlin@hoa-project.net>2014-01-25 20:46:35 +0100
commitb43f65c84c6f896bc7a1c7234b758fe3cb2c993c (patch)
tree9423d4cee29d2454577e43377e1796568e9a3ed3
parent5655de9dd481f51be6926102d2072886fe16bdb4 (diff)
downloadView-b43f65c84c6f896bc7a1c7234b758fe3cb2c993c.zip
View-b43f65c84c6f896bc7a1c7234b758fe3cb2c993c.tar.gz
View-b43f65c84c6f896bc7a1c7234b758fe3cb2c993c.tar.bz2
Write the english documentation.
-rw-r--r--Documentation/En/Index.xyl228
1 files changed, 226 insertions, 2 deletions
diff --git a/Documentation/En/Index.xyl b/Documentation/En/Index.xyl
index 6fa3e8f..8833ab9 100644
--- a/Documentation/En/Index.xyl
+++ b/Documentation/En/Index.xyl
@@ -3,8 +3,232 @@
<overlay xmlns="http://hoa-project.net/xyl/xylophone">
<yield id="chapter">
- <p class="warning">This chapter is not yet translated. Contributions are
- welcomed!</p>
+ <p><strong>Views</strong> are <strong>complex</strong> and
+ <strong>diversified</strong> systems. <code>Hoa\View</code> proposes an
+ interface able to match the majority of requirements through a
+ <strong>modular</strong> and <strong>extensible</strong> mechanism.</p>
+
+ <h2 id="Table_of_contents">Table of contents</h2>
+
+ <tableofcontents id="main-toc" />
+
+ <h2 id="Introduction" for="main-toc">Introduction</h2>
+
+ <p>A <strong>view</strong> is a mechanism allowing to graphically organize
+ <strong>data</strong> to a user. Many approaches exist, sometimes quite
+ <strong>different</strong> from each other and some of them can be very
+ <strong>complex</strong>. The <code>Hoa\View</code> library proposes one
+ interface that gathers the <strong>essential</strong> features in order to
+ integrate a view inside any other library.</p>
+
+ <h2 id="One_interface" for="main-toc">One interface</h2>
+
+ <p>The main mechanism of a view is almost always the same:</p>
+ <ul>
+ <li>we have <strong>data</strong> that we would like to
+ <strong>organize</strong> and <strong>print</strong> to the user,</li>
+ <li>a view also uses <strong>resources</strong> we must be able to
+ localize,</li>
+ <li>finally, the <strong>rendering</strong> is the process that computes a
+ result (organized data, linked resources etc.).</li>
+ </ul>
+ <p>Thus, we have four notions: data, a “renderer”, a router and an output
+ channel where to write the result.</p>
+ <p>The <code>Hoa\View</code> library proposes only one
+ <strong>interface</strong>: <code>Hoa\View\Viewable</code>. This latter
+ defines a method for each preceding notion:</p>
+ <ul>
+ <li><code>getData</code>, the data to organize,</li>
+ <li><code>getRouter</code>, to localize resources and other documents,</li>
+ <li><code>render</code>, our “renderer”, which will trigger the
+ rendering,</li>
+ <li><code>getOutputStream</code>, the stream where to write the view.</li>
+ </ul>
+ <p>And that's all! To be more accurate, here are the expected returned values
+ for each method:</p>
+ <ul>
+ <li><code>getData</code> should preferably return a
+ <code>Hoa\Core\Data</code> object (see <a href="@lh:chapter=Core">the
+ <code>Hoa\Core</code> library</a>); nevertheless, it is possible to return
+ any kind of objects,</li>
+ <li><code>getRouter</code> must return a router of kind
+ <code>Hoa\Router\Router</code> (see <a href="@lh:chapter=Router">the
+ <code>Hoa\Router</code> library</a>),</li>
+ <li><code>render</code> returns a void value,</li>
+ <li><code>getOutputStream</code> must return a stream implementing the
+ <code>Hoa\Stream\IStream\Out</code> interface (see
+ <a href="@lh:chapter=Stream">the <code>Hoa\Stream</code> library</a>); it
+ can be a file, a string, an HTTP response…</li>
+ </ul>
+ <p>Even if this approach may seem simplistic at first sight, this interface
+ covers the majority of requirements, and allows you to write the view you like
+ with your own or existing tools.</p>
+
+ <h2 id="Example" for="main-toc">Example</h2>
+
+ <p><a href="@lh:chapter=Xyl">The <code>Hoa\Xyl</code> library</a> uses
+ <code>Hoa\View\Viewable</code>, but it is a little bit complex for a first
+ example (which must not prevent you to take a look at it!). That's why we are
+ going to give a more simple and basic example.</p>
+ <p>Let's start to define what we want. We would like to have a mechanism of
+ views and <strong>sub-views</strong>, answering to the following
+ characteristics:</p>
+ <ul>
+ <li>a main view that controls the rendering,</li>
+ <li>this main view can include <strong>sub-views</strong>,</li>
+ <li>data will be <strong>isolated</strong>, which means that a view will not
+ be allowed to access to the data of another view,</li>
+ <li>data will hold in a
+ <a href="http://php.net/reserved.classes"><code>StdClass</code> class</a>
+ for more simplicity.</li>
+ </ul>
+ <p>Let's start by writting the <code>SuperView</code> class:</p>
+ <pre data-line="44"><code class="language-php">class SuperView implements Hoa\View\Viewable {
+
+ protected $_in = null;
+ protected $_out = null;
+ protected $_data = null;
+ protected $_router = null;
+
+ public function __construct ( $in,
+ Hoa\Stream\IStream\Out $out,
+ Hoa\Router\Router $router = null,
+ StdClass $data = null ) {
+
+ if(null === $data)
+ $data = new StdClass();
+
+ $this->_in = $in;
+ $this->_out = $out;
+ $this->_data = $data;
+ $this->_router = $router;
+
+ return;
+ }
+
+ public function getOutputStream ( ) {
+
+ return $this->_out;
+ }
+
+ public function getData ( ) {
+
+ return $this->_data;
+ }
+
+ public function render ( ) {
+
+ $data = $this->getData();
+ $router = $this->getRouter();
+
+ ob_start();
+ require $this->_in;
+ $content = ob_get_contents();
+ ob_end_clean();
+
+ $this->getOutputStream()->writeAll($content);
+
+ return;
+ }
+
+ public function getRouter ( ) {
+
+ return $this->_router;
+ }
+}</code></pre>
+ <p>Very classic. Our constructor asks a file to read, an output stream, an
+ optional router, and optional data. We find our <code>getOutputStream</code>,
+ <code>getData</code>, <code>render</code> and <code>getRouter</code> methods.
+ The <code>render</code> method will include the
+ <code class="language-php">$in</code> file by having formerly declared two
+ variables (in addition to <code class="language-php">$this</code>), namely
+ <code class="language-php">$data</code> and
+ <code class="language-php">$router</code>, to ease the usage. Finally, the
+ line 44 uses the output stream to write computed data.</p>
+ <p>Now, let's test by writing a <code>Test.php</code> file:</p>
+ <pre data-line="9,17"><code class="language-php">// Output.
+$output = new Hoa\Http\Response();
+
+// Router.
+$router = new Hoa\Router\Http();
+$router->get('a', '/Foo\.html');
+
+// View.
+$superview = new SuperView('Out.phtml', $output, $router);
+
+// Data.
+$data = $superview->getData();
+$data->title = 'foobar';
+$data->foo = (object) array('bar' => 'baz', 'qux' => 'hop');
+
+// Render.
+$superview->render();</code></pre>
+ <p>And finally, let's write our <code>Out.phtml</code> file:</p>
+ <pre><code class="language-markup">&amp;lt;h1>&amp;lt;?php echo $data->title; ?>&amp;lt;/h1></code></pre>
+ <p>Now, let's observe the result of the execution of <code>Test.php</code>:</p>
+ <pre><code class="language-shell">$ php Test.php
+&amp;lt;h1>foobar&amp;lt;/h1></code></pre>
+ <p>Excellent. Now, we will add the <code>import</code> method to create
+ <strong>sub-views</strong>. Thus, in the <code>SuperView</code> class:</p>
+ <pre><code class="language-php"> public function import ( $in, $data = null ) {
+
+ $new = new static(
+ $in,
+ $this->getOutputStream(),
+ $this->getRouter(),
+ $data
+ );
+ $new->render();
+
+ return;
+ }</code></pre>
+ <p>We use the <code>static</code> keyword to make a static reference to the
+ class itself, or to its children (see <a href="http://php.net/lsb">Late Static
+ Bindings</a>).</p>
+ <p>Nested views appear. Let's modify <code>Out.phtml</code> in order that it
+ uses <code>Sub.phtml</code> which will be a new view. To this sub-view, we
+ will just give a subset of data (only <code>foo</code>):</p>
+ <pre><code class="language-markup">&amp;lt;h1>&amp;lt;?php echo $data->title; ?>&amp;lt;/h1>
+
+&amp;lt;?php $this->import('Sub.phtml', $data->foo); ?></code></pre>
+ <p>And in <code>Sub.phtml</code>, we are free to use those data. Bonus: we
+ will use the router to create a link (as a reminder, the router defined the
+ <code>a</code> rule to <code>/Foo.html</code>). Thus:</p>
+ <pre><code class="language-markup">&amp;lt;p>Sub-view! This is a link:
+ &amp;lt;a href="&amp;lt;?php echo $router->unroute('a'); ?>">click click&amp;lt;/a>!&amp;lt;/p>
+
+&amp;lt;ul>
+&amp;lt;?php foreach($data as $key => $value): ?>
+ &amp;lt;li>&amp;lt;?php echo $key, ' => ', $value; ?>&amp;lt;/li>
+&amp;lt;?php endforeach; ?>
+&amp;lt;/ul></code></pre>
+ <p>Let's execute <code>Test.php</code> again to see the result:</p>
+ <pre><code class="language-shell">$ php Test.php
+&amp;lt;h1>foobar&amp;lt;/h1>
+
+&amp;lt;p>Sub-view! This is a link:
+ &amp;lt;a href="/Foo.html">click click&amp;lt;/a>!&amp;lt;/p>
+
+&amp;lt;ul>
+ &amp;lt;li>bar => baz&amp;lt;/li>
+ &amp;lt;li>qux => hop&amp;lt;/li>
+&amp;lt;/ul></code></pre>
+ <p>Our sub-view is in place, with our link and our isolated data (we iterate
+ over all of them without having <code>title</code>, only
+ <code>foo</code>).</p>
+ <p>This <code>SuperView</code> class is very basic but the
+ <strong>performances</strong> are interesting because the result of the
+ rendering is sent <strong>directly</strong> in the output stream, without
+ never manipulating heavy strings. This becomes particularly interesting when
+ we manipulate a lot of nested sub-views for example.</p>
+
+ <h2 id="Conclusion" for="main-toc">Conclusion</h2>
+
+ <p>The <code>Hoa\View</code> library defines only one
+ <strong>interface</strong> with four <strong>methods</strong>. After a period
+ of use, we understand that those methods are <strong>enough</strong> to
+ describe and manipulate many view systems potentially
+ <strong>complex</strong>.</p>
</yield>
</overlay>