- TwigZola2015-01-22T00:00:00+00:00https://www.fullstackstanley.com/tags/twig/atom.xmlUsing Eloquent, Twig and Slim PHP - Revisited2015-01-22T00:00:00+00:002015-01-22T00:00:00+00:00https://www.fullstackstanley.com/articles/using-eloquent-twig-and-slim-php-revisited/<p>It’s been about one and a half years since I made my blog post <a href="https://fullstackstanley.com/articles/using-eloquent-twig-and-slim-php">Using Eloquent, Twig and Slim PHP</a> and a lot’s changed since then but I still love using these three tools for small websites.</p>
<p>You can view all the code for this post <a href="https://github.com/acoustep/slim-twig-eloquent">here</a> or if you’re looking for the original code from 2013 please switch to the 1.0 release.</p>
<span id="continue-reading"></span><h2 id="what-s-changed">What’s changed?</h2>
<h3 id="migrations">Migrations</h3>
<p>The main update to the repo is migrations. I’ve added <a href="https://github.com/robmorgan/phinx">robmorgan/phinx
</a> because i’ve found nothing better outside of Laravel. I did use <a href="https://github.com/ruckus/ruckusing-migrations">ruckus/ruckusing-migrations</a> for the longest time but switched because I was unsatisfied with setting up a sensible and simple configuration. In fairness, it’s been a while since I’ve used it and it may have improved since then.</p>
<h3 id="gulp-sass-and-coffeescript">Gulp, SASS and Coffeescript</h3>
<p>I use SASS and Coffeescript for all of my new projects. They are easy to remove/ignore if you don’t wish to use them. I’ve also added LESS support just because Gulp makes it so simple.</p>
<h3 id="console-commands">Console commands</h3>
<p>I find myself creating commands for automation fairly often these days. Due to Symfony/Console already being a dependency I thought I may as well include it with a couple of commands out of the box.</p>
<p><code>php ste serve</code></p>
<p>This is just a wrapper around PHP’s built-in local server. I am always googling the arguments for it so I thought I’d just create a shorter command for convenience.</p>
<p><code>php ste model:make</code></p>
<p>This command takes one argument: your model’s name. It then generates the file for you and runs <code>composer dumpautoload</code> so you don’t have to worry about it.</p>
<h3 id="structure">Structure</h3>
<p>The structure is <em>mostly</em> the same. Obviously I’ve added directories for assets. But I’ve also removed <code>app/application.php</code> as the current version of Slim no longer requires the extra code. I’ve also made use of Phinx’s configuration file so you don’t have to update the same variables more than once.</p>
<p>There’s a new directory, <code>app/commands</code>, with the 2 commands mentioned above. This also lets you create your own commands fairly easily for your own automation needs.</p>
<h3 id="whoops">Whoops</h3>
<p><a href="https://github.com/filp/whoops">I really like this package</a>.</p>
<h2 id="issues">Issues</h2>
<p>The biggest issue I had was in fact rather simple to fix. I was getting no output from <code>writeln()</code> after requiring <code>vendor/autoload.php</code> in my console application.</p>
<p>If there’s one thing that’s worse than a convoluted error message it’s no error message at all.</p>
<p>Whoops ended up being the cause of my woes. After disabling Whoops for command line I could see exceptions again!</p>
<p>Another issue was unexpected Symfony/YAML behaviour. Turns out that when YAML parser can’t find the required file it just returns a string with the filename. This took me far longer than I care to admit to figure out.</p>
<h2 id="moving-forward">Moving forward</h2>
<p>As of writing this blog I’ve released an alpha version of the slim-twig-eloquent rewrite and I’m pretty happy with it. I have a couple of small changes to make and I’d like to write a few tests at least for the command line application.</p>
<p>If there’s one thing about Slim that bums me out it’s how difficult it is to test. I did find a nice package for testing but it’s not compatible with Slim 2.5. I’ve decided to hold off on adding testing for now.</p>
<p>I am also interested in the idea of a separate installer package which would allow you to run <code>ste new ProjectName</code> and generate a fresh install of the git repo. </p>
<p>I’ll leave that for another day and another blog post!</p>
Using Eloquent, Twig and Slim PHP2013-08-07T00:00:00+00:002013-08-07T00:00:00+00:00https://www.fullstackstanley.com/articles/using-eloquent-twig-and-slim-php/<p><em>Note</em>: See the <a href="/articles/using-eloquent-twig-and-slim-php-revisited">update to this post</a> where I've made several changes</p>
<p>Originally while I was writing this blog I intended to make a step by
step guide to putting together three of my favourite PHP tools. After a
few issues and finding out that <a href="https://github.com/codeguy/Slim-Views">Slim Views</a> is now a thing I decided
instead to put together a git repo so anyone can get started quickly. I
will use this blog post to quickly show how it works!</p>
<p>*Note that this tutorial doesn’t aim to teach you Slim, Twig or Eloquent</p>
<ul>
<li>It’s to show you how to use them together effectively.*</li>
</ul>
<p>You can find the repo here: <a href="https://github.com/acoustep/slim-twig-eloquent">https://github.com/acoustep/slim-twig-eloquent</a></p>
<p>After following the Installation instructions you should be able to use each component as well as Eloquent validation.</p>
<span id="continue-reading"></span><h3 id="folder-structure">Folder Structure</h3>
<ul>
<li>app/
<ul>
<li>config/</li>
<li>models/</li>
<li>views/</li>
<li>routes.php</li>
<li>application.php</li>
<li>Validator.php</li>
</ul>
</li>
<li>public/ (or public_html/)
<ul>
<li>css/</li>
<li>js/</li>
<li>images/</li>
<li>.htaccess</li>
<li>index.php</li>
</ul>
</li>
<li>vendor/</li>
<li>config.php</li>
<li>index.php</li>
</ul>
<p>As the <code>public/index.php</code> calls <code>/index.php</code> from the root of the application which then includes <code>config.php</code>, <code>app/application.php</code> and <code>app/routes.php</code>.</p>
<p><code>app/application.php</code> sets Slim, Twig and Eloquent up so that you can create all of your Slim routes in <code>app/routes.php</code>.</p>
<h3 id="example-usage">Example Usage</h3>
<p>Assuming you've now run <code>git clone https://github.com/acoustep/slim-twig-eloquent.git</code>, <code>composer install</code>, renamed the <code>config.php</code> file and changed your database settings let's create a table. I've opted to use MySQL - here's the query to make a <code>posts</code> table:</p>
<pre data-lang="sql" style="background-color:#2b303b;color:#c0c5ce;" class="language-sql "><code class="language-sql" data-lang="sql"><span style="color:#b48ead;">CREATE TABLE </span><span>`</span><span style="color:#8fa1b3;">posts</span><span>` (
</span><span> `</span><span style="color:#a3be8c;">id</span><span>` </span><span style="color:#b48ead;">int</span><span>(</span><span style="color:#d08770;">10</span><span>) unsigned NOT </span><span style="color:#d08770;">NULL</span><span> AUTO_INCREMENT,
</span><span> `</span><span style="color:#a3be8c;">title</span><span>` </span><span style="color:#b48ead;">varchar</span><span>(</span><span style="color:#d08770;">255</span><span>) NOT </span><span style="color:#d08770;">NULL</span><span>,
</span><span> `</span><span style="color:#a3be8c;">content</span><span>` </span><span style="color:#b48ead;">text </span><span>NOT </span><span style="color:#d08770;">NULL</span><span>,
</span><span> `</span><span style="color:#a3be8c;">created_at</span><span>` </span><span style="color:#b48ead;">datetime </span><span>NOT </span><span style="color:#d08770;">NULL</span><span>,
</span><span> `</span><span style="color:#a3be8c;">updated_at</span><span>` </span><span style="color:#b48ead;">timestamp </span><span>NOT </span><span style="color:#d08770;">NULL </span><span style="color:#b48ead;">DEFAULT </span><span style="color:#96b5b4;">CURRENT_TIMESTAMP</span><span>,
</span><span> </span><span style="color:#b48ead;">PRIMARY KEY</span><span> (`</span><span style="color:#a3be8c;">id</span><span>`)
</span><span>) ENGINE=InnoDB </span><span style="color:#b48ead;">DEFAULT</span><span> CHARSET=utf8 AUTO_INCREMENT=</span><span style="color:#d08770;">1</span><span> ;
</span></code></pre>
<p>A simple table with an unique id integer, title string, content text, created_at datetime and updated_at timestamp.</p>
<p>Next for the routes. Enter the following in <code>app/routes.php</code>:</p>
<pre data-lang="php" style="background-color:#2b303b;color:#c0c5ce;" class="language-php "><code class="language-php" data-lang="php"><span style="color:#ab7967;"><?php
</span><span style="color:#65737e;">/* new */
</span><span>$</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">get</span><span>( '</span><span style="color:#a3be8c;">/posts/new</span><span>', </span><span style="color:#b48ead;">function </span><span>() </span><span style="color:#b48ead;">use </span><span>( $</span><span style="color:#bf616a;">app</span><span>, $</span><span style="color:#bf616a;">data </span><span>) {
</span><span> $</span><span style="color:#bf616a;">data</span><span>['</span><span style="color:#a3be8c;">post</span><span>'] = </span><span style="color:#b48ead;">new </span><span style="color:#ebcb8b;">Post</span><span>;
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">render</span><span>( '</span><span style="color:#a3be8c;">posts_new.twig</span><span>', $</span><span style="color:#bf616a;">data </span><span>);
</span><span>})-></span><span style="color:#bf616a;">name</span><span>( '</span><span style="color:#a3be8c;">posts_new</span><span>' );
</span><span>
</span><span style="color:#65737e;">/* create */
</span><span>$</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">post</span><span>( '</span><span style="color:#a3be8c;">/posts</span><span>', </span><span style="color:#b48ead;">function </span><span>() </span><span style="color:#b48ead;">use </span><span>( $</span><span style="color:#bf616a;">app</span><span>, $</span><span style="color:#bf616a;">data </span><span>) {
</span><span> $</span><span style="color:#bf616a;">post </span><span>= </span><span style="color:#b48ead;">new </span><span style="color:#ebcb8b;">Post</span><span>;
</span><span> $</span><span style="color:#bf616a;">post</span><span>-></span><span style="color:#bf616a;">title </span><span>= $</span><span style="color:#bf616a;">_POST</span><span>['</span><span style="color:#a3be8c;">title</span><span>'];
</span><span> $</span><span style="color:#bf616a;">post</span><span>-></span><span style="color:#bf616a;">content </span><span>= $</span><span style="color:#bf616a;">_POST</span><span>['</span><span style="color:#a3be8c;">content</span><span>'];
</span><span> </span><span style="color:#b48ead;">if</span><span>( $</span><span style="color:#bf616a;">post</span><span>-></span><span style="color:#bf616a;">validate</span><span>( </span><span style="color:#96b5b4;">array</span><span>(
</span><span> '</span><span style="color:#a3be8c;">title</span><span>' => $</span><span style="color:#bf616a;">_POST</span><span>['</span><span style="color:#a3be8c;">title</span><span>'],
</span><span> '</span><span style="color:#a3be8c;">content</span><span>' => $</span><span style="color:#bf616a;">_POST</span><span>['</span><span style="color:#a3be8c;">content</span><span>']
</span><span> )))
</span><span> {
</span><span> $</span><span style="color:#bf616a;">post</span><span>-></span><span style="color:#bf616a;">save</span><span>();
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">flash</span><span>( '</span><span style="color:#a3be8c;">notice</span><span>', "</span><span style="color:#a3be8c;">you're post has been created</span><span>" );
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">redirect</span><span>( $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">urlFor</span><span>( '</span><span style="color:#a3be8c;">posts_index</span><span>' ) );
</span><span> }
</span><span> </span><span style="color:#b48ead;">else
</span><span> {
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">flash</span><span>( '</span><span style="color:#a3be8c;">error</span><span>', '</span><span style="color:#a3be8c;">your post was not valid</span><span>' );
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">flash</span><span>( '</span><span style="color:#a3be8c;">errors</span><span>', $</span><span style="color:#bf616a;">post</span><span>-></span><span style="color:#bf616a;">errors</span><span>() );
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">redirect</span><span>( $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">urlFor</span><span>( '</span><span style="color:#a3be8c;">posts_new</span><span>' ) );
</span><span> }
</span><span>})-></span><span style="color:#bf616a;">name</span><span>( '</span><span style="color:#a3be8c;">posts_create</span><span>' );
</span><span>
</span><span style="color:#65737e;">/* view all */
</span><span>$</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">get</span><span>( '</span><span style="color:#a3be8c;">/posts</span><span>', </span><span style="color:#b48ead;">function </span><span>() </span><span style="color:#b48ead;">use </span><span>( $</span><span style="color:#bf616a;">app</span><span>, $</span><span style="color:#bf616a;">data </span><span>) {
</span><span> $</span><span style="color:#bf616a;">data</span><span>['</span><span style="color:#a3be8c;">posts</span><span>'] = </span><span style="color:#ebcb8b;">Post</span><span>::</span><span style="color:#bf616a;">all</span><span>();
</span><span> $</span><span style="color:#bf616a;">app</span><span>-></span><span style="color:#bf616a;">render</span><span>( '</span><span style="color:#a3be8c;">posts.twig</span><span>', $</span><span style="color:#bf616a;">data </span><span>);
</span><span>})-></span><span style="color:#bf616a;">name</span><span>( '</span><span style="color:#a3be8c;">posts_index</span><span>' );
</span></code></pre>
<p>Above there are three routes. GET <code>/posts</code> to view all posts, GET <code>/posts/new</code> to enter a new post and POST <code>/posts</code> to create the post. On lines 9 and 31 you can see calls to a class <code>Post</code> which we will create shortly in our models directory. On line 12 you can see that you can use <code>$posts->validate()</code> to verify entered input.</p>
<p>Here's the model along with validation located in<code>app/models/Post.php</code></p>
<pre data-lang="php" style="background-color:#2b303b;color:#c0c5ce;" class="language-php "><code class="language-php" data-lang="php"><span style="color:#ab7967;"><?php
</span><span style="color:#b48ead;">class </span><span style="color:#ebcb8b;">Post </span><span style="color:#b48ead;">extends </span><span style="color:#a3be8c;">Illuminate\Database\Eloquent\Model
</span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">protected </span><span>$</span><span style="color:#bf616a;">table </span><span>= '</span><span style="color:#a3be8c;">posts</span><span>'</span><span style="color:#eff1f5;">;
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">private </span><span>$</span><span style="color:#bf616a;">errors</span><span style="color:#eff1f5;">;
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">private </span><span>$</span><span style="color:#bf616a;">rules </span><span>= </span><span style="color:#96b5b4;">array</span><span style="color:#eff1f5;">(
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">title</span><span>' => '</span><span style="color:#a3be8c;">required|between:4,16</span><span>'</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">content</span><span>' => '</span><span style="color:#a3be8c;">required|min:3</span><span>'
</span><span style="color:#eff1f5;"> );
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">private </span><span>$</span><span style="color:#bf616a;">messages </span><span>= </span><span style="color:#96b5b4;">array</span><span style="color:#eff1f5;">(
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">required</span><span>' => '</span><span style="color:#a3be8c;">Your :attribute is required.</span><span>'</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">min</span><span>' => '</span><span style="color:#a3be8c;">Your :attribute must be at least :min characters long.</span><span>'</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">max</span><span>' => '</span><span style="color:#a3be8c;">Your :attribute must be a maximum of :max characters long.</span><span>'</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">between</span><span>' => '</span><span style="color:#a3be8c;">Your :attribute must be between :min - :max characters long.</span><span>'</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;"> </span><span>'</span><span style="color:#a3be8c;">email</span><span>' => '</span><span style="color:#a3be8c;">Your :attribute must be a valid email address</span><span>'
</span><span style="color:#eff1f5;"> );
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public function </span><span style="color:#8fa1b3;">validate</span><span style="color:#eff1f5;">(</span><span>$</span><span style="color:#bf616a;">params</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;"> {
</span><span style="color:#eff1f5;"> </span><span>$</span><span style="color:#bf616a;">validator </span><span>= </span><span style="color:#ebcb8b;">Validator</span><span style="color:#eff1f5;">::</span><span style="color:#bf616a;">make</span><span style="color:#eff1f5;">( </span><span>$</span><span style="color:#bf616a;">params</span><span style="color:#eff1f5;">, </span><span>$</span><span style="color:#bf616a;">this</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">rules</span><span style="color:#eff1f5;">, </span><span>$</span><span style="color:#bf616a;">this</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">messages </span><span style="color:#eff1f5;">);
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">if</span><span style="color:#eff1f5;">( </span><span>$</span><span style="color:#bf616a;">validator</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">fails</span><span style="color:#eff1f5;">() )
</span><span style="color:#eff1f5;"> {
</span><span style="color:#eff1f5;"> </span><span>$</span><span style="color:#bf616a;">this</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">errors </span><span>= $</span><span style="color:#bf616a;">validator</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">errors</span><span style="color:#eff1f5;">()-></span><span style="color:#bf616a;">all</span><span style="color:#eff1f5;">();
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">false</span><span style="color:#eff1f5;">;
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">return </span><span style="color:#d08770;">true</span><span style="color:#eff1f5;">;
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public function </span><span style="color:#8fa1b3;">errors</span><span style="color:#eff1f5;">()
</span><span style="color:#eff1f5;"> {
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">return </span><span>$</span><span style="color:#bf616a;">this</span><span style="color:#eff1f5;">-></span><span style="color:#bf616a;">errors</span><span style="color:#eff1f5;">;
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">}
</span></code></pre>
<p><em>Validation is entirely optional - If you do not require validation just create the class and extend <code>Illuminate\Database\Eloquent\Model</code></em></p>
<p>At this point we just need to create our views - but before that you should run <code>composer update</code> so that your new model can be automatically loaded.</p>
<p>All templates are kept in <code>app/views</code></p>
<p>posts.twig</p>
<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>{% extends 'layout.twig' %}
</span><span>
</span><span>{% block content %}
</span><span> <</span><span style="color:#bf616a;">ul</span><span>>
</span><span> {% for post in posts %}
</span><span> <</span><span style="color:#bf616a;">li</span><span>>{{ post.title }}</</span><span style="color:#bf616a;">li</span><span>>
</span><span> {% else %}
</span><span> There are no posts here :(
</span><span> {% endfor %}
</span><span> </</span><span style="color:#bf616a;">ul</span><span>>
</span><span> <</span><span style="color:#bf616a;">a </span><span style="color:#d08770;">href</span><span>="</span><span style="color:#a3be8c;">{{ urlFor('posts_new') }}</span><span>">Create Post</</span><span style="color:#bf616a;">a</span><span>>
</span><span>{% endblock %}
</span></code></pre>
<p>posts_new.twig</p>
<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>{% extends 'layout.twig' %}
</span><span>
</span><span>{% block content %}
</span><span> <</span><span style="color:#bf616a;">form </span><span style="color:#d08770;">action</span><span>="</span><span style="color:#a3be8c;">{{ urlFor('posts_create') }}</span><span>" </span><span style="color:#d08770;">method</span><span>="</span><span style="color:#a3be8c;">post</span><span>">
</span><span> {% if flash.error %}
</span><span> <</span><span style="color:#bf616a;">p</span><span>>{{ flash.error }}</</span><span style="color:#bf616a;">p</span><span>>
</span><span> {% if flash.errors %}
</span><span> <</span><span style="color:#bf616a;">ul</span><span>>
</span><span> {% for error in flash.errors %}
</span><span> <</span><span style="color:#bf616a;">li</span><span>>{{ error }}</</span><span style="color:#bf616a;">li</span><span>>
</span><span> {% endfor %}
</span><span> </</span><span style="color:#bf616a;">ul</span><span>>
</span><span> {% endif %}
</span><span> {% endif %}
</span><span> <</span><span style="color:#bf616a;">input </span><span style="color:#d08770;">type</span><span>="</span><span style="color:#a3be8c;">text</span><span>" </span><span style="color:#d08770;">name</span><span>="</span><span style="color:#a3be8c;">title</span><span>" </span><span style="color:#d08770;">placeholder</span><span>="</span><span style="color:#a3be8c;">Title</span><span>">
</span><span> <</span><span style="color:#bf616a;">br</span><span>>
</span><span> <</span><span style="color:#bf616a;">input </span><span style="color:#d08770;">type</span><span>="</span><span style="color:#a3be8c;">text</span><span>" </span><span style="color:#d08770;">name</span><span>="</span><span style="color:#a3be8c;">content</span><span>" </span><span style="color:#d08770;">placeholder</span><span>="</span><span style="color:#a3be8c;">Content</span><span>">
</span><span><</span><span style="color:#bf616a;">br</span><span>>
</span><span> <</span><span style="color:#bf616a;">input </span><span style="color:#d08770;">type</span><span>="</span><span style="color:#a3be8c;">submit</span><span>" </span><span style="color:#d08770;">value</span><span>="</span><span style="color:#a3be8c;">Create</span><span>">
</span><span> </</span><span style="color:#bf616a;">form</span><span>>
</span><span>{% endblock %}
</span></code></pre>
<p>layout.twig (Put your layout in here as usual)</p>
<pre data-lang="php" style="background-color:#2b303b;color:#c0c5ce;" class="language-php "><code class="language-php" data-lang="php"><span>{% block content %}
</span><span>{% endblock %}
</span></code></pre>
<p>As you can see, Slim functions are available with <code>urlFor()</code> being called on line 11 in <code>posts.twig</code> and line 4 in <code>posts_new.twig</code>. You can also use Slim's flash functionality to send messages to redirections. At this point everything should work!</p>
<h3 id="custom-configurations">Custom Configurations</h3>
<p>Perhaps you don't want your templates to be in a view folder, you want to disable twig caching or change error reporting for different environments?</p>
<p>99% of the magic inside of <code>app/application.php</code>. This is where Slim is instantiated along with Twig and Eloquent. Make sure that you take a look so you can perfect your own set up!</p>
<h3 id="resources">Resources</h3>
<p>While putting this together I came across some links which helped me out a lot. Here are as many as I can remember:</p>
<ul>
<li><a href="http://www.slimframework.com/news/slim-and-laravel-eloquent-orm">Slim and Laravel Eloquent ORM</a></li>
<li><a href="https://github.com/codeguy/Slim-Extras/pull/58">Fix Class 'Twig_Extensions_Slim' not found</a></li>
<li><a href="http://www.12devsofxmas.co.uk/post/2012-12-29-day-4-mixing-and-matching-php-components-with-composer">Mixing and Matching PHP Components with Composer</a></li>
<li><a href="https://github.com/codeguy/Slim-Views">Slim Views</a></li>
</ul>