Nashvile Symfony Routes Presentation

Post on 15-May-2015

2,464 views 0 download

Tags:

description

A presentation for the Nashville Symfony User's Group on October 1st, 2009. The presentation featured ways to extend the Symfony routing classes.

transcript

woot.woot.

Symfony Routing!Symfony Routing!

Basic RoutingBasic Routing

// /apps/myapp/config/routing.ymlfoo_route: url: /my/custom/path param: { module: default, action: index }

bar_route: url: /another/custom/path param: { module: default action: index, bar: true }

foo_bar_route: url: /:foo/:bar param: { module: default, action: index }

// /apps/myapp/config/routing.ymlfoo_route: url: /my/custom/path param: { module: default, action: index }

bar_route: url: /another/custom/path param: { module: default action: index, bar: true }

foo_bar_route: url: /:foo/:bar param: { module: default, action: index }

<?php echo link_to('Click Here', '@foo_bar_route?foo=that&bar=NOW!', array('target' => '_blank')); ?><?php echo link_to('Click Here', '@foo_bar_route?foo=that&bar=NOW!', array('target' => '_blank')); ?>

configuration:configuration:

in your template:in your template:

<a href='/that/NOW!' target="_blank">Click Here</a><a href='/that/NOW!' target="_blank">Click Here</a>

Basic Object RoutingBasic Object Routing

// /apps/myapp/config/routing.ymlfoo_route: class: sfDoctrineRoute url: /member/:username param: { module: default, action: index } options: { type: object, model: sfGuardUser }

bar_route: class: sfDoctrineRouteCollection options: { model: Page, module: page, prefix_path: page, column: id, with_wildcard_routes: true }

foobar: class: sfDoctrineRouteCollection options: model: Foo module: foo prefix_path: foo/:bar_id column: id with_wildcard_routes: true

// /apps/myapp/config/routing.ymlfoo_route: class: sfDoctrineRoute url: /member/:username param: { module: default, action: index } options: { type: object, model: sfGuardUser }

bar_route: class: sfDoctrineRouteCollection options: { model: Page, module: page, prefix_path: page, column: id, with_wildcard_routes: true }

foobar: class: sfDoctrineRouteCollection options: model: Foo module: foo prefix_path: foo/:bar_id column: id with_wildcard_routes: true

configuration:configuration:

sfDoctrineRouteCollectionsfDoctrineRouteCollection

foobar GET /foobar.:sf_formatfoobar_new GET /foobar/new.:sf_formatfoobar_create POST /foobar.:sf_formatfoobar_edit GET /foobar/:id/edit.:sf_formatfoobar_update PUT /foobar/:id.:sf_formatfoobar_delete DELETE /foobar/:id.:sf_formatfoobar_show GET /foobar/:id.:sf_formatfoobar_object GET /foobar/:id/:action.:sf_formatfoobar_collection POST /foobar/:action/action.:sf_format

foobar GET /foobar.:sf_formatfoobar_new GET /foobar/new.:sf_formatfoobar_create POST /foobar.:sf_formatfoobar_edit GET /foobar/:id/edit.:sf_formatfoobar_update PUT /foobar/:id.:sf_formatfoobar_delete DELETE /foobar/:id.:sf_formatfoobar_show GET /foobar/:id.:sf_formatfoobar_object GET /foobar/:id/:action.:sf_formatfoobar_collection POST /foobar/:action/action.:sf_format

Try: $ ./symfony app:routes myapp Try: $ ./symfony app:routes myapp

It’s RESTful!It’s RESTful!

More Advanced RoutingMore Advanced Routing

•First Step: Overloading your classes•First Step: Overloading your classes

Setting a Default Route ClassSetting a Default Route Class

# /apps/myapp/config/config_handlers.ymlconfig/routing.yml: class: myRoutingConfigHandler

# /apps/myapp/config/config_handlers.ymlconfig/routing.yml: class: myRoutingConfigHandler

•Configure which classes parse your YAML files•Register your handler class in your project configuration•Config files are parsed before classes are autoloaded

•Configure which classes parse your YAML files•Register your handler class in your project configuration•Config files are parsed before classes are autoloaded

Question: How do you configure the config_handlers handler??Question: How do you configure the config_handlers handler??

do this only if you’re very lazydo this only if you’re very lazy

<?php// /config/config.php$configCache = sfProjectConfiguration::getActive()->getConfigCache();$configCache->registerConfigHandler('config/routing.yml', 'myRoutingConfigHandler');

<?php// /config/config.php$configCache = sfProjectConfiguration::getActive()->getConfigCache();$configCache->registerConfigHandler('config/routing.yml', 'myRoutingConfigHandler');

<?php/*** Sets default routing class*/class myRoutingConfigHandler extends sfRoutingConfigHandler{ protected function parse($configFiles) { // ... $routes[$name] = array(isset($params['class']) ? $params['class'] : $this->getDefaultRouteClass(), array( $params['url'] ? $params['url'] : '/', isset($params['params']) ? $params['params'] : (isset($params['param']) ? $params['param'] : array()), isset($params['requirements']) ? $params['requirements'] : array(), isset($params['options']) ? $params['options'] : array(), )); } } return $routes; } public function getDefaultRouteClass() { $default = sfConfig::get('app_routing_route_class'); return $default ? $default : 'sfRoute'; }}

<?php/*** Sets default routing class*/class myRoutingConfigHandler extends sfRoutingConfigHandler{ protected function parse($configFiles) { // ... $routes[$name] = array(isset($params['class']) ? $params['class'] : $this->getDefaultRouteClass(), array( $params['url'] ? $params['url'] : '/', isset($params['params']) ? $params['params'] : (isset($params['param']) ? $params['param'] : array()), isset($params['requirements']) ? $params['requirements'] : array(), isset($params['options']) ? $params['options'] : array(), )); } } return $routes; } public function getDefaultRouteClass() { $default = sfConfig::get('app_routing_route_class'); return $default ? $default : 'sfRoute'; }}

Setting a Default Route ClassSetting a Default Route Class•Extend the sfRoutingConfigHandler class to return a configurable default route class•Extend the sfRoutingConfigHandler class to return a configurable default route class

Subdomain routingSubdomain routing

# apps/*/config/routing.ymlhomepage_sub1: url: / param: { module: main, action: homepage1 } class: sfRequestHostRoute requirements: sf_host: sub1.example.com homepage_sub2: url: / param: { module: main, action: homepage2 } class: sfRequestHostRoute requirements: sf_host: sub2.example.com

# apps/*/config/routing.ymlhomepage_sub1: url: / param: { module: main, action: homepage1 } class: sfRequestHostRoute requirements: sf_host: sub1.example.com homepage_sub2: url: / param: { module: main, action: homepage2 } class: sfRequestHostRoute requirements: sf_host: sub2.example.com

•Create a custom route Class (we are using sfRequestHostRoute)

•specify your subdomain in route requirements•note: Don’t Forget! Routes of class sfRoute can still match this url without subdomains.

•Create a custom route Class (we are using sfRequestHostRoute)

•specify your subdomain in route requirements•note: Don’t Forget! Routes of class sfRoute can still match this url without subdomains.

class sfRequestHostRoute extends sfRequestRoute{ public function matchesUrl($url, $context = array()) { if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host']) { return false; } return parent::matchesUrl($url, $context); }}

class sfRequestHostRoute extends sfRequestRoute{ public function matchesUrl($url, $context = array()) { if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host']) { return false; } return parent::matchesUrl($url, $context); }}

Subdomain routingSubdomain routing•Create sfREquestHostRoute class, extend sfRequestRoute•Overload matchesUrl method - This method is called on all routes declared in routing.yml until one returns true•check ‘host’ requirement. If it matches, continue to match the url. return false otherwise

•Create sfREquestHostRoute class, extend sfRequestRoute•Overload matchesUrl method - This method is called on all routes declared in routing.yml until one returns true•check ‘host’ requirement. If it matches, continue to match the url. return false otherwise

Subdomain routing (cont)Subdomain routing (cont)

class sfRequestHostRoute extends sfRequestRoute{ // ... public function generate($params, $context = array(), $absolute = false) { $url = parent::generate($params, $context, $absolute); if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host']) { // apply the required host $protocol = $context['is_secure'] ? 'https' : 'http'; $url = $protocol.'://'.$this->requirements['sf_host'].$url; } return $url; }}

class sfRequestHostRoute extends sfRequestRoute{ // ... public function generate($params, $context = array(), $absolute = false) { $url = parent::generate($params, $context, $absolute); if (isset($this->requirements['sf_host']) && $this->requirements['sf_host'] != $context['host']) { // apply the required host $protocol = $context['is_secure'] ? 'https' : 'http'; $url = $protocol.'://'.$this->requirements['sf_host'].$url; } return $url; }}

•Overload generate method (called when using link_to and url_for methods, etc.)•If this route has an sf_host requirement set, add this to the generated url, and prepend to the matching host•This will ensure links reroute to the new subdomain

•Overload generate method (called when using link_to and url_for methods, etc.)•If this route has an sf_host requirement set, add this to the generated url, and prepend to the matching host•This will ensure links reroute to the new subdomain

<?php

class myRequestHostRoute extends sfRoute{ protected $_subdomains = array('foo', 'bar'), $_root = 'dev.localhost', $_default = 'www';

public function matchesUrl($url, $context = array()) { if (!in_array($context['sf_host'], $this->_subdomains)) { return false; } return parent::matchesUrl($url, $context); } // ...}

<?php

class myRequestHostRoute extends sfRoute{ protected $_subdomains = array('foo', 'bar'), $_root = 'dev.localhost', $_default = 'www';

public function matchesUrl($url, $context = array()) { if (!in_array($context['sf_host'], $this->_subdomains)) { return false; } return parent::matchesUrl($url, $context); } // ...}

Dynamic Subdomain routingDynamic Subdomain routing

•Turns Passed Parameter “subdomain” into a subdoman (as long as it’s in the array of specified subdomains)•Turns Passed Parameter “subdomain” into a subdoman (as long as it’s in the array of specified subdomains)

note: this class is untestednote: this class is untested

public function generate($params, $context = array(), $absolute = false) { $url = parent::generate($params, $context, false); // if accessing by ip or different domain, bypass subdomain routing if (!strstr($context['host'], $this->_root)) { return $url; } // apply the required host $protocol = $context['is_secure'] ? 'https' : 'http'; // if the subdomain is set, and is in our list of known subdomains if (isset($params['subdomain']) && in_array($params['subdomain'], $this->_subdomains)) { $url = $protocol.'://'. $params['subdomain'].'.'.$this->_root.$url; } else { // use class default if subdomain does not exist $url = $protocol.'://'.$this->_default.'.'.$this->_root.$url; }

return $url; }}

public function generate($params, $context = array(), $absolute = false) { $url = parent::generate($params, $context, false); // if accessing by ip or different domain, bypass subdomain routing if (!strstr($context['host'], $this->_root)) { return $url; } // apply the required host $protocol = $context['is_secure'] ? 'https' : 'http'; // if the subdomain is set, and is in our list of known subdomains if (isset($params['subdomain']) && in_array($params['subdomain'], $this->_subdomains)) { $url = $protocol.'://'. $params['subdomain'].'.'.$this->_root.$url; } else { // use class default if subdomain does not exist $url = $protocol.'://'.$this->_default.'.'.$this->_root.$url; }

return $url; }}

Dynamic Subdomain routing (cont)Dynamic Subdomain routing (cont)

See http://healthandwellness.vanderbilt.edu to see dynamic subdomain routing in action See http://healthandwellness.vanderbilt.edu to see dynamic subdomain routing in action