Skip to content

Instantly share code, notes, and snippets.

@birkir
Last active December 17, 2015 20:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save birkir/5670679 to your computer and use it in GitHub Desktop.
Save birkir/5670679 to your computer and use it in GitHub Desktop.
Kohana 3.3 application with Red Bean and Twig
  1. Preperation steps

git clone git://github.com/kohana/kohana yourdomain.com
cd yourdomain.com
git submodule update --init
rm install.php
cd application
chmod 0777 cache
chmod 0777 logs
echo '{"require": {"gabordemooij/redbean": "dev-master", "twig/twig": "v1.13.0" }}' >> composer.json
curl -s https://getcomposer.org/installer | php
php composer.phar install
  1. Create files

Copy the files to APPPATH/classes/Controller, and APPPATH/views.

Note: dashes in file name represent directory seperator (slash).

  1. Update bootstrap.php and enjoy

Edit your APPPATH/bootstrap.php (base_url, index_file, lang etc.)

echo -e "\nCookie::$salt = 'your salt key';\n" >> bootstrap.php
echo -e "\nrequire_once Kohana::find_file('vendor', 'autoload');" >> bootstrap.php

Optional: change your default controller to 'book' to show on the index page. (@line: 128)

Book library done!

<?php defined('SYSPATH') or die('No direct script access.');
use RedBean_Facade as R;
class Controller_Book extends Controller_Main {
public function action_index()
{
// proxy list
return $this->action_list();
}
public function action_list()
{
// find all items with redbean
$items = R::findAll('book', 'ORDER BY '.Arr::get($this->request->query(), 'sort', 'title').' ASC');
// render template with twig and found items
$this->view = $this->twig->render('book/list.html', array(
'items' => $items
));
}
public function action_new()
{
// get post parameters
$item = $this->request->post();
// capture request on post
if ($this->request->method() === HTTP_Request::POST)
{
// create book from array
$book = R::dispense('book')
->import($item, 'title,author,summary');
// store the book
R::store($book);
// redirect user
HTTP::redirect('book/list');
}
// attach to template and render
$this->view = $this->twig->render('book/fieldset.html', array(
'item' => $item
));
}
public function action_edit()
{
// load book
$item = R::load('book', $this->request->param('id'));
// lookup results
if ( ! $item->id)
throw Kohana_Exception('Book not found.');
// capture request on post
if ($this->request->method() === HTTP_Request::POST)
{
// update book attributes from array
$item->import($this->request->post(), 'title,author,summary');
// store the book
R::store($item);
}
// attach to template and render
$this->view = $this->twig->render('book/fieldset.html', array(
'item' => $item
));
}
public function action_delete()
{
// load book
if ($item = R::load('book', $this->request->param('id')))
// trash the book
R::trash($item);
// back to list
HTTP::redirect('book/list');
}
} // End Book
<?php defined('SYSPATH') or die('No direct script access.');
use RedBean_Facade as R;
class Controller_Main extends Controller {
public $rb;
public $twig;
public $template = 'template.html';
public $view = NULL;
public function before()
{
// setup redbeans
$this->rb = R::setup();
// twig template engine
$this->twig = new Twig_Environment(new Twig_Loader_Filesystem(APPPATH.'views'), array(
'autoescape' => FALSE,
'debug' => TRUE,
'cache' => APPPATH.'cache/twig'
));
// list of allowed helpers in twig
$helpers = array('Arr', 'Cookie', 'Date', 'Feed', 'File', 'Form', 'Fragment', 'HTML', 'Inflector', 'Num', 'Profiler', 'Text', 'URL', 'Upload');
// loop through list of helpers
foreach ($helpers as $helper)
{
// add helper as global twig variable
$this->twig->addGlobal(strtolower($helper), new $helper());
}
return parent::before();
}
public function after()
{
$template = $this->twig->render($this->template, array(
'view' => $this->view
));
$this->response->body($template);
return parent::after();
}
} // End Main
<h1>{% if item.id %}Edit {{ item.title }} {% else %} New book {% endif %}</h1>
{{ form.open('', {class: 'form-horizontal'}) }}
<div class="control-group">
{{ form.label('bookTitle', 'Title', {class: 'control-label'}) }}
<div class="controls">
{{ form.input('title', item.title|e, {id: 'bookTitle'}) }}
</div>
</div>
<div class="control-group">
{{ form.label('bookAuthor', 'Author', {class: 'control-label'}) }}
<div class="controls">
{{ form.input('author', item.author|e, {id: 'bookAuthor'}) }}
</div>
</div>
<div class="control-group">
{{ form.label('bookSummary', 'Summary', {class: 'control-label'}) }}
<div class="controls">
{{ form.textarea('summary', item.summary|e, {rows: 4}) }}
</div>
</div>
<div class="form-actions">
{{ form.button('save', 'Save book', {class: 'btn btn-primary', type: 'submit'}) }}
{{ html.anchor('book/list', 'Cancel', {class: 'btn'}) }}
</div>
{{ form.close }}
<h1>List of books</h1>
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Actions</th>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>{{ item.title|e }}</td>
<td>{{ item.author|e }}</td>
<td>
<a href="{{ url.site('book/edit/' ~ item.id) }}" title="Edit"><i class="icon-edit"></i></a>
<a href="{{ url.site('book/delete/' ~ item.id) }}" title="Delete"><i class="icon-trash"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ url.site('book/new') }}" class="btn">Create book</a>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Book library</title>
<link href="http://todc.github.io/todc-bootstrap/assets/css/bootstrap.css" rel="stylesheet">
<link href="http://todc.github.io/todc-bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet">
<link href="http://todc.github.io/todc-bootstrap/assets/css/todc-bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
{{ view }}
</div>
<script src="http://todc.github.io/todc-bootstrap/assets/js/jquery.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment