skipping controller name from URL in symfony 1.4 - php

I've an existing project in symfony 1.4
For static pages, we use a module Page which give following URLs:
http://www.example.com/page/aboutus
http://www.example.com/page/faq
http://www.example.com/ (page/index method, points to method page/home)
For new requirements, we need URL in format:
http://www.example.com/aboutus
http://www.example.com/faq
http://www.example.com/ (index/home method of page module; working as page is default module)
There are 16 such static pages and all are listed under page module. As of now I'm planning to create 16 new modules with putting each static page in index method of new module but I guess its a bad solution and hope symfony is definitely not designed to be used in this way.
Is there any way to skip module name from URL, at least for default module?

You might want to use a rewrite rule as explained in
http://corz.org/serv/tricks/htaccess2.php

Use the route feature of symfony!
In routing.yml:
aboutus_page:
url: /aboutus
param: { module: page, action: aboutus }
faq_page:
url: /faq
params: { module: page, action: faq }
home_page:
url: /
params: { module: page, action: index }
# your other routes
# ...
The actions.class.php of your page module will look like:
class pageActions extends sfActions
{
public function executeAboutus (sfWebRequest $request)
{
// ...
}
public function executeFaq (sfWebRequest $request)
{
// ...
}

Related

Symfony 1.4 url_for empty string behavior

I'm working on a Symfony 1.4 project and when I do this:
url_for('');
I'm expecting to get the URL for the index.php controller or at least http://domain/ but I'm getting this:
/sfTCPDF
sfTCPDF is a plugin that I have in this project that in my config/ProjectConfiguration.class.php is used like:
class ProjectConfiguration extends sfProjectConfiguration {
public function setup() {
$this->enablePlugins('sfTCPDFPlugin');
}
}
When I disable the plugin I get the expected result:
$url = url_for('');
> /
Or when I use it like this (Doesn't matter if the plugin is enabled or not):
$url = url_for('/');
> /
I don't understand why the plugin is causing (or even if it's the plugin fault).
Any suggestions? I can search & replace the entire project for url_for('') and put the '/'
But I really want to understand why this is happening.
After some research:
I found out that when the url_for function is called, the procedure is the next:
lib/vendor/symfony/lib/helper/UrlHelper.php url_for()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for2()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for1()
lib/vendor/symfony/lib/controller/sfWebController.class.php gen_url()
lib/vendor/symfony/lib/routing/sfRoute.class.php generate()
And in the last one it gets the $this->pattern here is where the pattern is sfTCPDF/:action
which means that some routing is playing. Continuing my research i found out that the plugin has a routing.yml with:
sfTCPDF:
url: /sfTCPDF/:action
param: { module: sfTCPDF, action: test }
If I delete this routing everything works as expected.
Now the question is: when do the plugin creates a routing object with the pattern of sfTCPDF and why?
I never use the url_for with an empty string.
In my routes file I use to have:
homepage:
url: /
param: { module: home, action: index }
So if I want the route for this, I use:
url_for('#homepage');
url_for uses the route name you provide to find the proper route in the cached routes table. If you provide an empty string it will take the 0 index from the table (which you can find in the file: cache/app/env/config/config_routing.yml.php.
When the TCPDF plugin is on its' route is being added as the first one that's why you get it as the url.
The solution - don't use an empty string for url_for. If you want to get the url of the homepage always use url_for('/') or url_for('#homepage').

symfony 1.4 routing: match routes using URL parameters

I have set up friendly URLs for a few search result pages, using a custom route for each:
friendly_search_resultpage:
url: /products/my-friendly-alias
param:
module: products
action: search
querystring: searchattribute
querystring2: searchattribute2
This works fine, but when doing the search directly (i.e. browsing to /products/search?querystring=search...) I want to set a <link rel="canonical"> containing the matching friendly URL. This will help Google understand the relation and that there isn't duplicate content.
I put my friendly URL route at the top of routes.yml and hoped for a magic match, but URL parameters aren't recognised in the checking done by symfony. I have dug into sfRoute, with no luck. Is it possible?
I ended up writing a custom routing class to use for these routes, which is executed when url_for() is called. Here is the code:
<?php
class mySearchFriendlyRoute extends sfRoute
{
public function matchesParameters($params, $context = array())
{
// I can't find symfony sorting parameters into order, so I do
// (so that foo=x&bar=y is treated the same as bar=y&foo=x)
ksort($params);
$mine = $this->defaults;
ksort($mine);
if ($params == $mine) {
return true;
}
return false;
}
}
To use, add class: mySearchFriendlyRoute to the routes.yml entry.
Try to use Your own Route:
friendly_search_resultpage:
class: YourRouteClassName
...
And overload sfRoute::generate() there by concrete cannonicalization (return the canonical URL).
This redirects with 301 in my project upon of last sf1.4 revision.

How Silverstripe URLs work?

I am new to Silverstripe Framework / CMS. I see ./mysite/code/Page.php as controller and ./themes/simple/... as template directory. I logged into the admin panel and added new test page. The menu appears on the website with the URL http://example.com/test and content is displayed.
So what I want to know is, how to access the new controller let say Download.ss. I want to access the URL http://example.com/download/123/ without adding the new page download in admin panel. Thank you.
First of all, any files with a .ss extension are template files not controllers.
Create a new class in mysite/code/Download.php which extends Controller.
class Download extends Controller {
public function index() {
// Automatically handles URLs like http://example.com/Download
}
public function exampleaction() {
// Automatically handles URLs like http://example.com/Download/exampleaction
}
}
After that you'll want to add a new routes.yml file to the mysite/_config directory to specify that the index function on your new controller should handle calls to http://example.com/download/123.
---
Name: downloadrules
---
Director:
rules:
'download/$ID': Download
Now the '123' portion of your example URL will be accessible as $this->request->param('ID') within the index function.
Now you can do:
class Download extends Controller {
public function index() {
$fileID = $this->request->param('ID');
// Do your thing.
}
}
Documentation for this stuff is at http://doc.silverstripe.org/framework/en/reference/director

magento indexControllor.php url rewriting not working properly

Hi i build a indexcontrollor in module brand like this
class Blank_Brand_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
echo 'Foo Index Action';
$this->addaction();
}
public function addAction()
{
echo 'Foo add Action';
$this->deleteAction();
}
}
When I put in the address: http://www.myshop.com/index.php/brand/, it echos Foo Index Action
With this URL, though, it does nothing: http://www.myshop.com/index.php/brand/add
What could be the problem here causing this? This could save a lot of problems for me which I have with URL rewriting in Magento!
It's a common oversight.
This url
http://www.myshop.com/index.php/brand/
is equivalent to this url
http://www.myshop.com/index.php/brand/index/index
The URI portion "brand" is your module. The first "index" URI portion is your controller, the second "index" URI portion is your action method.
Module: brand
Controller: index
Action: index
So, let's consider this URL
http://www.myshop.com/index.php/brand/add
This is equivalent to
http://www.myshop.com/index.php/brand/add/index
Which gives us
Module: brand
Controller: add
Action: index
The URL you're trying to call is looking for a controller named
class Blank_Brand_AddController ....
When it doesn't find one, it reports back 404.
If you wanted to call the addAction method on your index controller, you'd want the following URL
http://www.myshop.com/index.php/brand/index/add
I wrote an article on this - perhaps it would help: http://prattski.com/2010/06/24/magento-overriding-core-files-blocks-models-resources-controllers/

Making static pages in Symfony 1

Im new to symfony and have some simple questions. I am trying to understand the module system, but I dont understand how I create the actual homepage or other pages that are not based off of a model from the db. For example, the simple about page that has static info or the homepage that is a combination of a bunch of information from different models.
Can anyone help?
First of all, modules do not have to be restricted to a model from the database. You can have a Foo module which relies on no database content, and a Bar module that is primarily based on 3 different models. The module separation is a way to logically break up your site into manageable sections. Eg an e-commerce site might have a Products module, a Categories module and a Cart module and so on.
Your last sentence can then be split into 2 parts:
1) Static information can be on any page - if it's for things like "About us" and "FAQ" etc, I personally tend to use a "default" or "home" module, and create the various actions in there vis:
./symfony generate:module appname home
and
class homeActions extends sfActions
{
public function executeAbout(sfWebRequest $request)
{
// ...
}
public function executeFaq(sfWebRequest $request)
{
// ...
}
}
with the corresponding template files (aboutSuccess.php, faqSuccess.php).
2) A page can be comprised of data from many different models - just use your preferred ORM's method of retrieving data and set it to the view ($this->data = MyModel->findByColumn(...) etc). If you mean data from different modules, then you'd probably be better off looking at partials or components for elements of a page that can be used across different modules (navigation etc). See the Symfony docs for more details on these.
I'm used to handle static pages in this way.
First I create a new entry in apps/frontend/config/routing.yml:
page:
url: pages/:page
param: { module: page, action: index }
Then I write a "page" module (apps/frontend/modules/page/actions/actions.class.php):
<?php
class pageActions extends sfActions
{
public function executeIndex()
{
$this->page = $this->getRequestParameter("page");
$this->forward404Unless($this->_partialExists($this->page));
}
protected function _partialExists($name)
{
$directory = $this->getContext()->getModuleDirectory();
return (is_readable($directory.DIRECTORY_SEPARATOR."templates".
DIRECTORY_SEPARATOR."_".$name.".php"));
}
}
Last step, put in modules/page/templates/indexSuccess.php this code:
<?php include_partial($page); ?>
So all you have to do from now is to create a partial for each static page ie.
apps/frontend/modules/page/templates/_home.php which you can reach at
http://yousite/pages/home (without the need to add a new routing entry for every page)
You can create a module, e.g. called static and create actions for every static page or only one action that delivers the page depending on a request variable. The only thing this action does is loading a template.
IMHO it would be good if symfony comes with a default module for this.
For example actions of (my custom) module static:
class staticActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
if(!$request->hasParameter('site')) {
return sfView::ERROR;
}
$this->site = $request->getParameter('site');
}
}
With this template:
//indexSuccess.php
<?php include_partial($site) ?>
The actual statics sites are all partials.
In my routing.yml looks like this:
# static stuff
about:
url: /about
param: {module: static, action: index, site: about}
This way you only have to create a new partial and a new routing entry when you add a static site and you don't have to touch the PHP code.
Another way to serve static pages without having to write any controller code is to set up the route something like the following:
myStaticPage:
pattern: /pageName
defaults:
_controller: FrameworkBundle:Template:template
template: MyBundle:Home:pageName.html.twig
Then just create your twig template and it should work fine.
Apart from the above, consider having a CMS for static pages, so you won't need technical savy people to mantain them or change them. This depends on the project, of course.
For really static and independent pages you can simply create any file in [pathToYourProjectRoot]/web directory.
It may by i.e. [pathToYourProjectRoot]/web/assets/static_html/about.html.
Then link to the page directly by http://your.site.com/assets/static_html/about.html.

Categories