SlideShare a Scribd company logo
1 of 12
woot.
Symfony Routing!
Basic Routing
// /apps/myapp/config/routing.yml
foo_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.yml
foo_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:
in your template:
<a href='/that/NOW!' target="_blank">Click Here</a><a href='/that/NOW!' target="_blank">Click Here</a>
Basic Object Routing
// /apps/myapp/config/routing.yml
foo_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.yml
foo_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:
sfDoctrineRouteCollection
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
It’s RESTful!
More Advanced Routing
•First Step: Overloading your classes
Setting a Default Route Class
# /apps/myapp/config/config_handlers.yml
config/routing.yml:
class: myRoutingConfigHandler
# /apps/myapp/config/config_handlers.yml
config/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
Question: How do you configure the config_handlers handler??
do 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 Class
•Extend the sfRoutingConfigHandler class to return a configurable default route
class
Subdomain routing
# apps/*/config/routing.yml
homepage_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.yml
homepage_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.
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 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
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
<?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 routing
•Turns Passed Parameter “subdomain” into a subdoman (as long as it’s in the
array of specified subdomains)
note: 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)
See http://healthandwellness.vanderbilt.edu to see dynamic subdomain routing in action

More Related Content

What's hot

Apostrophe
ApostropheApostrophe
Apostrophetompunk
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentTammy Hart
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門Yusuke Wada
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linuxtutorialsruby
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking Sebastian Marek
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
vfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsvfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsFrank Kleine
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2zfconfua
 
There's a Filter For That
There's a Filter For ThatThere's a Filter For That
There's a Filter For ThatDrewAPicture
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks Damien Seguy
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 

What's hot (20)

Apostrophe
ApostropheApostrophe
Apostrophe
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linux
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
PHP 8.1: Enums
PHP 8.1: EnumsPHP 8.1: Enums
PHP 8.1: Enums
 
vfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsvfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent tests
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
 
There's a Filter For That
There's a Filter For ThatThere's a Filter For That
There's a Filter For That
 
Perl5i
Perl5iPerl5i
Perl5i
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 

Similar to Nashvile Symfony Routes Presentation

Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareKuan Yen Heng
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Binary Studio Academy 2016: Laravel Routing
Binary Studio Academy 2016: Laravel Routing Binary Studio Academy 2016: Laravel Routing
Binary Studio Academy 2016: Laravel Routing Binary Studio
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframeworkRadek Benkel
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngineMichaelRog
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsBastian Hofmann
 
AngularJS - $http & $resource Services
AngularJS - $http & $resource ServicesAngularJS - $http & $resource Services
AngularJS - $http & $resource ServicesEyal Vardi
 
Codeigniter : Custom Routing - Manipulate Uri
Codeigniter : Custom Routing - Manipulate UriCodeigniter : Custom Routing - Manipulate Uri
Codeigniter : Custom Routing - Manipulate UriAbdul Malik Ikhsan
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowVrann Tulika
 

Similar to Nashvile Symfony Routes Presentation (20)

Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Binary Studio Academy 2016: Laravel Routing
Binary Studio Academy 2016: Laravel Routing Binary Studio Academy 2016: Laravel Routing
Binary Studio Academy 2016: Laravel Routing
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 
AngularJS - $http & $resource Services
AngularJS - $http & $resource ServicesAngularJS - $http & $resource Services
AngularJS - $http & $resource Services
 
Codeigniter : Custom Routing - Manipulate Uri
Codeigniter : Custom Routing - Manipulate UriCodeigniter : Custom Routing - Manipulate Uri
Codeigniter : Custom Routing - Manipulate Uri
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 

More from Brent Shaffer

HTTP - The Protocol of Our Lives
HTTP - The Protocol of Our LivesHTTP - The Protocol of Our Lives
HTTP - The Protocol of Our LivesBrent Shaffer
 
OAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army FrameworkOAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army FrameworkBrent Shaffer
 
Why Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled GarbageWhy Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled GarbageBrent Shaffer
 
OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)Brent Shaffer
 
In The Future We All Use Symfony2
In The Future We All Use Symfony2In The Future We All Use Symfony2
In The Future We All Use Symfony2Brent Shaffer
 
Nashville Symfony Functional Testing
Nashville Symfony Functional TestingNashville Symfony Functional Testing
Nashville Symfony Functional TestingBrent Shaffer
 
Nashville Php Symfony Presentation
Nashville Php Symfony PresentationNashville Php Symfony Presentation
Nashville Php Symfony PresentationBrent Shaffer
 

More from Brent Shaffer (9)

Web Security 101
Web Security 101Web Security 101
Web Security 101
 
HTTP - The Protocol of Our Lives
HTTP - The Protocol of Our LivesHTTP - The Protocol of Our Lives
HTTP - The Protocol of Our Lives
 
OAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army FrameworkOAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army Framework
 
Why Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled GarbageWhy Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled Garbage
 
OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)
 
In The Future We All Use Symfony2
In The Future We All Use Symfony2In The Future We All Use Symfony2
In The Future We All Use Symfony2
 
Symfony Events
Symfony EventsSymfony Events
Symfony Events
 
Nashville Symfony Functional Testing
Nashville Symfony Functional TestingNashville Symfony Functional Testing
Nashville Symfony Functional Testing
 
Nashville Php Symfony Presentation
Nashville Php Symfony PresentationNashville Php Symfony Presentation
Nashville Php Symfony Presentation
 

Recently uploaded

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 

Recently uploaded (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 

Nashvile Symfony Routes Presentation

  • 2. Basic Routing // /apps/myapp/config/routing.yml foo_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.yml foo_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: in your template: <a href='/that/NOW!' target="_blank">Click Here</a><a href='/that/NOW!' target="_blank">Click Here</a>
  • 3. Basic Object Routing // /apps/myapp/config/routing.yml foo_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.yml foo_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:
  • 4. sfDoctrineRouteCollection 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 It’s RESTful!
  • 6. •First Step: Overloading your classes Setting a Default Route Class # /apps/myapp/config/config_handlers.yml config/routing.yml: class: myRoutingConfigHandler # /apps/myapp/config/config_handlers.yml config/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 Question: How do you configure the config_handlers handler?? do 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');
  • 7. <?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 Class •Extend the sfRoutingConfigHandler class to return a configurable default route class
  • 8. Subdomain routing # apps/*/config/routing.yml homepage_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.yml homepage_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.
  • 9. 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 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
  • 10. 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
  • 11. <?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 routing •Turns Passed Parameter “subdomain” into a subdoman (as long as it’s in the array of specified subdomains) note: this class is untested
  • 12. 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) See http://healthandwellness.vanderbilt.edu to see dynamic subdomain routing in action