YASC
Yet Another Sinatra Clone, (*1)
yasc is a sinatra (kind of) clone written in php
and highly influenced by zend framework 1.x, the routing system is based on
limonade's code, is a tiny framework that uses user defined functions as actions
(like in the MVC pattern) and annotations to route the requested url to a function., (*2)
Features
- Functions based.
- RESTful.
- Tiny ^_^.
- Routing system based on regex patterns, named params, pairs param (like zend framework 1.x).
- View helpers.
- Function helpers.
- Layouts support.
- Class autoloading based on the Framework Interop Group.
- Models support.
Default project structure
yasc uses this project structure:, (*3)
app.php
views/
helpers/
models/
If you create these folders in your project they are auto-loaded in your application. Default namespaces:, (*4)
helpers/Helper_*
models/Model_*
Accessors
I saw that invoking the requested function with a lot of arguments is too ugly and a little
bit verbose (just a little?), so I add some accessors to be used in each function., (*5)
run(__NAMESPACE__);
unset($yasc);
```
Add a function and a pattern using an annotation for your application index,
your script will be something like this:
```php
run(__NAMESPACE__);
unset($yasc);
/**
* @GET("/")
*/
function index() {
echo "Hello world!";
}
```
Now, go to your favorite browser and run your script:
http://localhost/app.php
Follow the examples and you'r done :).
Setup
-----
Maybe you want to *hide* your script file from the URL, http://app.com/app.php/some/thing (I know, pretty URLs, SEO shut, blah, blah)
and get something fancier like: http://app.com/some/thing, ok, well, create a [VirtualHost](http://httpd.apache.org/docs/2.0/vhosts/)
and add a [.htaccess](http://corz.org/serv/tricks/htaccess2.php) file to your application folder like this:
### Virtual host configuration
DocumentRoot "/path/to/your/application/public"
ServerName app.com
Options -Indexes MultiViews FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
### .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
**NOTE:** Your app file must be named index.php in order to work with this `.htaccess` file.
Simple Example
--------------
```php
run(__NAMESPACE__);
unset($yasc);
/**
* @GET("/")
*/
function index() {
echo "Hello world!";
}
/**
* @POST("/")
*/
function create() {
// save something.
}
/**
* @PUT("/")
*/
function update() {
// update something.
}
/**
* @DELETE("/")
*/
function destroy() {
// delete something.
}
```
Configuration
-------------
```php
setLayoutScript(dirname(__FILE__) . "/layouts/default.phtml");
// * If you want to use a stream wrapper to convert markup of mostly-PHP
// templates into PHP prior to include(), seems like is a little bit slow,
// so by default is off.
// ->setViewStream(true);
//
// * You can add more than one folder to store views, each view script
// is a .phtml file.
// ->addViewsPath(dirname(__FILE__) . "/extra_views");
//
// * You can add more than one path of view helpers and set a
// class prefix for the path added.
// ->addViewHelpersPath(dirname(__FILE__) . "/../library/My/View/Helper", "My_View_Helper");
//
// or if you don't want a class prefix just leave it blank.
// ->addViewHelpersPath(dirname(__FILE__) . "/extra_views/helpers");
//
// * Function helpers, second argument is a prefix class.
// ->addFunctionHelpersPath(dirname(__FILE__) . "/extra_function_helpers");
//
// * Add models folder, second argument is a prefix class.
// ->addModelsPath(dirname(__FILE__) . "/models");
// ->addModelsPath(dirname(__FILE__) . "/extra_models/My/Model", "My_Model");
//
// * Add extra options to the configuration object, like some $mysql connection
// resource or a global flag, etc.
// ->addOption("db", $mysql);
}
```
Pre- and Post-Dispatch Hooks
----------------------------
We provide two functions, `pre_dispatch` and `post_dispatch`, that may be called before and after an action is
invoked.
Advanced Examples
-----------------
```php
disable(), Yasc_Layout uses singleton pattern.
Yasc_App::view()->layout()->disable();
// Get the mysql resource from this app configuration option.
//
// $mysql = Yasc_App::config()->getOption("db");
//
// ... do some sql operation.
echo "Hello world!";
}
/**
* @POST("/")
*
* You can route the same url to another function using a different request
* method.
*/
function save_index() {
Yasc_App::view()->layout()->disable();
echo "";
echo "post: ";
var_dump($_POST);
echo "";
}
/**
* @GET("/tales")
*/
function tales() {
// You can add variables to the view object and get his value on
// the view script using the variable $this, like: $this->tales.
Yasc_App::view()->tales = "oh! I'm a view variable!";
// Render a view script, a view script is a .phtml file where you can mix
// php and html, the V in the MVC model, in this example the view files
// are stored in views/ folder.
//
// This view calls a view helper 'Tales', so check views/helpers/Tales.php
// to see what it does.
Yasc_App::view()->render("tales");
}
/**
* @GET("/tales/:lol")
* @POST("/woot") // Ignored, yasc only uses the first annotation found.
*
* Named params, you can access those via Yasc_App::params() method.
*
* Matches: /tales/foo and /tales/bar
*/
function tales1() {
Yasc_App::view()->layout()->disable();
echo "";
echo "lol value: " . Yasc_App::params("lol");
echo "";
Yasc_App::view()->tales = "oh! I'm a view variable!";
// instance of a model.
$foo = new Model_Foo();
Yasc_App::view()->helloModel = $foo->doSomething();
// Render a view without the layout.
Yasc_App::view()->render("tales");
}
/**
* @GET("/tales/:lol/id/:id")
*/
function tales2() {
Yasc_App::view()->layout()->disable();
echo "";
echo "lol value: " . Yasc_App::params("lol");
echo "id value: " . Yasc_App::params("id");
echo "";
}
/**
* @POST("/tales3")
*/
function tales3() {
Yasc_App::view()->layout()->disable();
echo "";
echo "post: ";
var_dump($_POST);
echo "";
}
/**
* @GET("/foo")
*/
function foo() {
// Render view script foo, this view script calls the view helper class 'Foo',
// this view helper render a view helper script inside and return his content
// to this view, a view helper script is just another .phtml file, if you don't
// want to create a whole html string inside the helper ;).
Yasc_App::view()->render("foo");
}
/**
* @GET("^/regex/id/(\d+)/name/([a-z]+)")
*
* You can create patterns using a regular expression, this kind of route must
* begin with a '^'. Check limonade docs and code if you want more information, or
* just use limonade framework :), it's a more robust framework.
*
* http://www.limonade-php.net/README.htm
* https://github.com/sofadesign/limonade/blob/master/lib/limonade.php
*
* Matches: /regex/id/26/name/juan
*/
function regex() {
Yasc_App::view()->layout()->disable();
echo "";
echo "params: ";
var_dump(Yasc_App::params());
echo "";
}
/**
* @GET("/say/*\/to\/*")
*
* Patterns may also include wildcard parameters. Each value is associted
* through numeric indexes, in the same order as in the pattern.
*
* Matches: /say/hello/to/world
*/
function single_asterisk() {
Yasc_App::view()->layout()->disable();
echo "";
echo "params: ";
var_dump(Yasc_App::params());
echo "hello: ";
var_dump(Yasc_App::params(0)); // hello
echo "world: ";
var_dump(Yasc_App::params(1)); // world
echo "";
}
/**
* @GET("/download/*.*")
*
* Matches: /download/file.xml
*/
function download() {
Yasc_App::view()->layout()->disable();
echo "";
echo "params: ";
var_dump(Yasc_App::params());
echo "filename: ";
var_dump(Yasc_App::params(0)); // file
echo "ext: ";
var_dump(Yasc_App::params(1)); // xml
echo "";
}
/**
* @GET("/writing/*\/to\/**")
*
* The double wildcard '**' matches a string like this one: my/friend/juan/badass,
* this string is treated as pairs, this way: param1/value1/param2/value2 etc, like
* Zend Framework does, so, via Yasc_App::params() method you can get those
* values using each key.
*
* Matches: /writing/hello/to/my/friends/from/limonade/you_guys/roxor
*/
function pairs() {
Yasc_App::view()->layout()->disable();
echo "";
echo "params: ";
var_dump(Yasc_App::params());
echo "single wildcard: ";
var_dump(Yasc_App::params(0)); // hello
echo "param my: ";
var_dump(Yasc_App::params("my")); // friend
echo "param from: ";
var_dump(Yasc_App::params("from")); // limonade
echo "param you_guys: ";
var_dump(Yasc_App::params("you_guys")); // roxor
echo "";
}
/**
* @GET("/update")
*/
function update() {
/* @var $flash Yasc_Function_Helper_Flash */
$flash = Yasc_App::functionHelper("flash");
Yasc_App::view()->flash = $flash;
return Yasc_App::view()->render("update");
// Use '_method' parameter in POST requests when PUT or DELETE methods
// are not supported.
/*