What would be the best way to check for the current URI segment in a CodeIgniter view? What I am trying to do is use the current URI segment [i.e. $this->uri->segment(1)] in order to highlight the current page on the navigation bar.
The best that I have figured out is to do
$data['current_uri'] = $this->uri->segment(1);
$this->load->view('header', $data);
in each of my controllers and then in the header.php file, I check the $current_uri variable to determine which part of the navigation should be highlighted. As you know, this is a very tedious way of doing it, but I'm at a loss of a better way to do this.
It may even be possible to extend the default Controller class to pass the current URI segment, but I'm not sure if this would work, or even how to go about doing it.
I myself use an extra function similar to anchor(). I call it active_anchor(), and it takes all the same parameters plus another (the uri). The function then adds the class 'active' if the uri string passed matches the active_anchor() url paramter.
Then the function returns using the anchor function (all that the function did was determine if the link needed the class 'active' or not.
EDIT:
I just put this code in a file called 'MY_url_helper.php'. That way, when the url helper is loaded (I actually auto load that one since pretty much all of my views use it anyway.) This is just some quick code too, pretty sure it would work. Basically it takes the same arguments as the anchor() function, but also the $key variable. It appends a class of "active" to the anchor tag if the key and url match.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('active_anchor'))
{
function active_anchor($url = NULL, $title = NULL, $key = NULL, $params = array())
{
if ($url && $key)
{
if($key == $url)
{
if (array_key_exists ('class' , $params))
{
$params['class'] .= ' active';
}
else
{
$params['class'] = 'active';
}
}
}
return anchor($url, $title, $params);
}
}
Simple way to check the uri segment in view,
Add some code if matches found.
<li class="<?php echo (strcmp($this->uri->segment(2),'test')==0)?'active':''; ?>"><li>
<li class="<?php echo (strcmp($this->uri->segment(2),'test1')==0)?'active':''; ?>"><li>
<li class="<?php echo (strcmp($this->uri->segment(2),'test2')==0)?'active':''; ?>"><li>
I also had the same problem when I was building a customer website in Cakephp, passing those strings for every menu item from controller to view, then checking again in view for implementing the highlighting to tedious to say the least.
For some of my projects now, I have been implementing the same by storing the page information for each of the navigation menu pages in database, things like page name, url, title, position in navigation menu etc.
Then at the start of controller, I store all this data in an array say $pageinfo.
I handle the navigation functionality via a single controller that checks the URI segment and loads the content based on that.
The highlighting part is left to an if statement when generating the view, where I compare each page name to the information I dumped in $pageinfo.
Something like this...
foreach ($navi_menu as $links) {
if ( $links['title'] == $pageinfo['title'] ) {
// Highlight here
}
else {
// No highlight
}
}
This way I don't need to pass the string constants (uri segments in your case) to the view. This CMS-kinda-approach allows me to flexible in adding further items to my menu, without adding more code.
I remember getting this from a codeigniter wiki, can't find the link to it right now.
this simple way and running well for me..
<li class="<?=($this->uri->segment(2)==='test')?'current-menu-item':''?>"><?php echo anchor ('home/index','HOME'); ?></li>
<li class="<?=($this->uri->segment(2)==='blog')?'current-menu-item':''?>"><?php echo anchor ('home/blog','BLOG'); ?></li>
<li class="<?=($this->uri->segment(2)==='bla..bla')?'current-menu-item':''?>"><?php echo anchor ('home/blog','bla..bla'); ?></li>
uri_segment(2) that mean function in ur controller.
but have a weakness, i have trouble if i put view in index controller, so im not use function index ( toruble in uri segment, make 2 current page in same time... read this http://ellislab.com/codeigniter/user-guide/libraries/uri.html
I'll probably get flamed for suggesting a client-side approach, but this is something I've used in the past to mark the current page as highlighted:
var path = location.pathname.substring(1);
if ( path )
$('#navigation a[href$="' + path + '"]').parents('li').attr('class', 'current');
In every CodeIgniter project I gather some basic information about the request in MY_Controller.
I extend the core controller and put in some initialization logic that needs to happen on every page. This includes getting the information about the controller and method, which is passed to the view. As a short example:
class MY_Controller extends CI_Controller
{
protected $_response_type = 'html';
protected $_secure;
protected $_dir;
protected $_controller;
protected $_method;
protected $_template;
protected $_view;
protected $_user;
public function __construct()
{
parent::__construct();
// Gather info about the request
$this->_secure = ! empty($_SERVER['HTTPS']);
$this->_dir = $this->router->fetch_directory();
$this->_controller = $this->router->fetch_class();
$this->_method = $this->router->fetch_method();
// set the default template and view
$this->_template = 'default';
$this->_view = $this->_dir . $this->_controller . '/' . $this->_method;
}
/**
* Performs operations right before data is displayed.
*
* #access public
* #return void
*/
public function _pre_display()
{
if ($this->_response_type === 'html') {
$this->load->vars(array(
'user' => $this->_user
));
}
elseif ($this->_response_type === 'json') {
$this->_template = 'json';
$this->_view = NULL;
}
else {
show_error('Invalid response type.');
}
$this->load->vars(array(
'is_secure' => $this->_secure,
'controller' => $this->_controller,
'method' => $this->_method
));
}
}
Now in a view such as the navigation you can use that information like this:
<a href="<?php echo site_url('products') ?>"<?php echo ($controller === 'products') ? ' class="selected"' : ''; ?>>Products</a>
I like it because with routes or rewrites you may access controllers and methods from different URLs. This way you set whether the link is active based on the controller/method that is serving up the content and not based on the URL.
Also, this information can be reused within your controllers or views for any reason and you are not continually asking the router or uri to calculate the information (which not only is inefficient, but is cumbersome to write over and over).
Related
I'm creating a webpage where students and teachers log in, teachers create levels and students can do that level.
I explain, I am using php with twig and I want to render a view passing parameters in a function. I've created a budle called Professors where I have the directory Controllers, Models and Templates.
In templates I have professors.html, where I show some information and a button to create a level for students, and also I have crearNivell.html, where the teacher will be able to create the level. When I'm in the page views professors my URL is this one:
When I click the button "CREATE LEVEL" I want my URL to be like this:
Instead I get this URL, and this one returns me an error.
In Controllers/ProfessorsController.php I have that code:
class ProfessorController extends Controller{
public function process($params)
{
/*var_dump($params);
die();*/
if(empty($params[0])){
$this->getProfessor(); //Here I return the view professor
}elseif(isset($params[0]) && $params[0] == "crearNivell"){
$this->twig = "crearNivell.html";
}
}
public function getProfessor(){
$this->twig = "professor.html";
}
}
Can someone help me with my code?
When I use var_dump() I get this:
and it should be like that:
I think what you're looking for is the API of Twig.
More specifically, you need the line below to render a template passing some parameters in array:
echo $template->render(['the' => 'variables', 'go' => 'here']);
If you use PHP the fastest way to "print" some content to the browser is echo, so don't hesitate to use it.
I found the answer to the questions a few days ago. I was complicating myself, it's just like this:
First you create the views, in Templates folder.
The $params are refered to the URL. For example:
alumne is the bundle
AlumneController.php
Then in AlumneController.php put the name of the views without the .html and you show it using $this->twig = "name_Of_The_View.html";
<?php
class AlumneController extends Controller{
public function process($params)
{
/*var_dump($params);
die();*/
if(empty($params[0])){
$this->getAlumne();
/*echo $usuari = $_SESSION["username"];*/
}else if(isset($params[0]) && $params[0] == "instruccions"){
$this->twig = "instruccions.html";
/*echo $usuari = $_SESSION["username"];*/
}else if(isset($params[0]) && $params[0] == "resultats"){
$this->twig = "resultats.html";
/*echo $usuari = $_SESSION["username"];*/
}
}
public function getAlumne(){
$this->twig = "alumne.html";
}
}
alumne.html
And in the button or link you are using to go to the page you write the path in Instruccions
<a class="mdl-navigation__link" href="alumne/instruccions">Instruccions</a>
<a class="mdl-navigation__link" href="alumne/resultats">Resultats</a>
This is an extension of my original question SilverStripe 3.1+ Dynamically creating page redirects
I have a product page URL
a) www.mysite.com/category/subcat/productid
You can visit this page via a a separate redirector page
b) www.mysite.com/productid
Page 'a' has tabs which can be visited via
c) www.mysite.com/category/subcat/productid/tabid
I would like to use PHP to dynamically create links / redirectors for each product page create so it can be visited by:
1) A short URL using only its 'predicted' shown in 'b' (I can do this by creating a page redirector but this is long winded for a large number of products.
2) Create a short URL for each tab link as well, so 'c' would be redirected from: d) www.mysite.com/productid/tabid
The 'tabid' can be hard coded and in my case would be: audio, videos, pictures, firmware
Currently using the code in my ProductPage.php
class ProductPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'audio',
'pictures',
'firmware',
'videos',
);
public function audio() {
$this->redirect($this->Link().'?tab=audio');
}
public function pictures() {
$this->redirect($this->Link().'?tab=pictures');
}
public function firmware() {
$this->redirect($this->Link().'?tab=firmware');
}
public function videos() {
$this->redirect($this->Link().'?tab=videos');
}
Allows me to go from /video to /?tab=video but this of course does not shorten the URL which is the final result I'm after.
Possibly this could be done in an extension of the RedirectorPage.php?
One way to do this is to use onBeforeHTTPError404 to hook into when a 404 error is called and to redirect any product found.
We create a ProductRedirectExtension with an onBeforeHTTPError404 function. This function will get called when a page cannot be found, but before the system returns a 404 error. The code in here will check if a ProductPage exists with a URLSegment with the first part of user's URL string. If a ProductPage is found we then check if the second part of the user's URL string is one of the tab keywords. After that the user is redirected to the page.
ProductRedirectExtension.php
class ProductRedirectExtension extends Extension {
public function onBeforeHTTPError404( $request ) {
$urlSegment = $request->param('URLSegment');
$action = strtolower($request->param('Action'));
$page = ProductPage::get()->filter('URLSegment', $urlSegment)->first();
if ($page) {
$link = $page->Link();
if ($action == 'audio' || $action == 'pictures' || $action == 'firmware' || $action == 'videos') {
$link .= '?tab=' . $action;
}
$response = new SS_HTTPResponse();
$response->redirect($link, 301);
throw new SS_HTTPResponse_Exception($response);
}
}
}
We enable this extension with the following config settings.
config.yml
RequestHandler:
extensions:
- ProductRedirectExtension
ContentController:
extensions:
- ProductRedirectExtension
ModelAsController:
extensions:
- ProductRedirectExtension
The shortest you could go is www.mysite.com/product/productid/tabid. It is possible to do this without the product part, but this would make your life a lot harder as you would have to go through a lot of trouble to still have access to Admin and Dev for example.
If you want the shortest URL you should make a new Page, as your current ProductPage is a child of another page, telling from your URL:
www.mysite.com/category/subcat/productid
You can achieve the best scenario with this code:
class ProductRedirectPage_Controller extends Page_Controller
{
private static $allowed_actions = [
'Product'
];
private static $url_handlers = [
'$ID/$TabID' => 'Product'
];
public function Product()
{
// Get your ProductPage, this should work if there is only one ProductPage
$page = ProductPage::get()->first();
if(! $productId = $this->request->param('ID'))
return $this->redirect($page->Link()); // or send them somewhere else
$tabId = $this->request->param('TabID');
$link = $page->Link('yourAction/' . $productId . '/' . $tabId);
return $this->redirect($link);
}
}
EDIT
With this code, when www.mysite.com/product/productid/tabid is visited, it will redirect you to where your ProductPage is. Maybe you wish to change the /$tabId to ?tabId=' . $tabId, but that is totally up to you.
So if I'm to summarise, you want newpage/video to open the correct on page tab, rather than being an action to render a different page?
You could do something funky with private static $url_handlers, to set a parameter you could query through $request->param('Thing').
Or you could set up handleAction to test whether or not $action either is one of the things in the list (and set flags for later use in eg. a template), or otherwise parent::handleAction.
This answer isn't extremely fleshed out, but should hopefully provide you some ideas on directions to investigate for your own use case.
OK, I think I am probably (hopefully) going to be told I am going about this in the wrong way.
Currently, if I go to root of CI web I call a function which reads a predefined location with map_directory(). I then iterate it out in a view as a simple directory listing.
I then want to click on one of these directories to see what's inside. When I do that I call a different controller function called browse.
So if I click on one link I go to
www.mysite.com/dir1
(which is Routed to www.mysite.com/controller/browse/$1 - where $1 in this instance = dir1).
Now I am presented with a dir listing of dir1. I have configured the links of the displayed listings to now go to:
www.mysite.com/dir1/subdir1 etc.
What I want to do and this might be the bit where I am cheating/going wrong, is capture everything after
www.mysite.com/
and pass it to
www.mysite.com/controller/browser/$1
So example:
www.mysite.com/dir1/subdir1/ => www.mysite.com/controller/browse/"dir1/subdir1"
I know I can't have '"' in there, but that's the bit I am trying to pass to the map_directory() function...so it goes /.$var (where $var would = $1 = "dir1/subdir1".
So far I have tried in CI Routes.php:
$route['(.+)$'] = 'controller/browse/$1';
$route['([a-zA-Z0-9\/]*)'] = 'controller/browse/$1';
$route['(:any)'] = 'controller/browse/$1';
...but they all only ever seem to capture "dir1" never anything beyond that.
I hope that makes sense to someone....
You can just use the special _remap() method in your controller to override the default routing behavior:
class Controller extends CI_Controller
{
protected function browse($path)
{
// ... do something with $path here
}
public function _remap($method, $params = array())
{
if ($method === 'browse')
{
$params = implode('/', $params);
return $this->browse($params);
}
elseif (method_exists($this, $method))
{
return call_user_func_array(array($this, $method), $params);
}
show_404();
}
}
Hi i wont to make something like that.
http:// example.com/ - Main Controller
http:// example.com/rules/ - Main Controller where content get from database, but if not exist
return 404 page. (It's ok, isn't problem.)
But if i have subfolder in application/controlles/rules/
I want to redirect it to Main Contorller at Rules folder.
This follow code can solve problem, but i don't know how it right realise.
At routes.php:
$route['default_controller'] = "main";
$route['404_override'] = '';
$dirtest = $route['(:any)'];
if (is_dir(APPPATH.'controllers/'.$dirtest)) {
$route['(:any)'] = $dirtest.'/$1';
} else {
$route['(:any)'] = 'main/index/$1';
}
Ok, what I have:
controllers/main.php
class Main extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('main_model');
}
public function index($method = null)
{
if (is_dir(APPPATH.'controllers/'.$method)) {
// Need re-rout to the application/controllers/$method/
} else {
if ($query = $this->main_model->get_content($method)) {
$data['content'] = $query[0]->text;
// it shows at views/main.php
} else {
show_404($method);
}
}
$data['main_content'] = 'main';
$this->load->view('includes/template', $data);
}
}
Updated Again (routes.php):
So, seem's like what i search (work example):
$route['default_controller'] = "main";
$route['404_override'] = '';
$subfolders = glob(APPPATH.'controllers/*', GLOB_ONLYDIR);
foreach ($subfolders as $folder) {
$folder = preg_replace('/application\/controllers\//', '', $folder);
$route[$folder] = $folder.'/main/index/';
$route[$folder.'/(:any)'] = $folder.'/main/$1';
}
$route['(:any)'] = 'main/index/$1';
But, in perfectly need some like this:
http:// example.com/1/2/3/4/5/6/...
Folder "controllers" has subfolder "1"?
YES: Folder "1" has subfolder "2"?
NO: Folder "1" has controller "2.php"?
NO: Controller "controllers/1/main.php" has function "2"?
YES: redirect to http:// example.com/1/2/ - where 3,4,5 - parameters..
It is realy nice, when you have structure like:
http://example.com/blog/ - recent blog's posts
http://example.com/blog/2007/ - recent from 2007 year blog's posts
http://example.com/blog/2007/06/ - same with month number
http://example.com/blog/2007/06/29/ - same with day number
http://example.com/blog/web-design/ - recent blog's post's about web design
http://example.com/blog/web-design/2007/ - blog' posts about web design from 2007 years.
http://example.com/blog/current-post-title/ - current post
Same interesting i find http://codeigniter.com/forums/viewthread/97024/#490613
I didn't thoroughly read your question, but this immediately caught my attention:
if (is_dir($path . '/' . $folder)) {
echo "$route['$folder/(:any)'] = '$folder/index/$1';"; //<---- why echo ???
}
Honestly I'm not sure why this didn't cause serious issues for you in addition to not working.
You don't want to echo the route here, that will just try to print the string to screen, it's not even interpreted as PHP this way. There are also some issues with quotes that need to be remedied so the variables can be read as variables, not strings. Try this instead:
if (is_dir($path . '/' . $folder)) {
$route[$folder.'/(:any)'] = $folder.'/index/$1';
}
Aside: I'd like to offer some additional resources that are not directly related to your problem, but should help you nonetheless with a solution:
Preferred way to remap calls to controllers: http://codeigniter.com/user_guide/general/controllers.html#remapping
Easier way to scan directories: http://php.net/manual/en/function.glob.php
It's hard to say why the registering of your routes fails. From your code I can see that you're not registering the routes (you just echo them), additionally I see that the usage of variables in strings are used inconsistently. Probably you mixed this a bit, the codeigniter documentation about routes is not precise on it either (in some minor points, their code examples are not really syntactically correct, but overall it's good).
I suggest you first move the logic to register your dynamic routes into a function of it's own. This will keep things a bit more modular and you can more easily change things and you don't pollute the global namespace with variables.
Based on this, I've refactored your code a bit. It does not mean that this works (not tested), however it might make things more clear when you read it:
function register_dynamic_routes($path, array &$route)
{
$nodes = scandir($path);
if (false === $nodes)
{
throw new InvalidArgumentException(sprintf('Path parameter invalid. scandir("$path") failed.', $path));
}
foreach ($nodes as $node)
{
if ($node === '.' or $node === '..')
continue
;
if (!is_dir("{$path}/{$node}")
continue
;
$routeDef = "{$folder}/(:any)";
$routeResolve = "{$folder}/index/\$1";
$route[$routeDef] = $routeResolve;
# FIXME debug output
echo "\$route['{$routeDef}'] = '{$routeResolve}';";
}
}
$path = APPPATH.'controllers/';
register_dynamic_routes($path, $route);
$route['(:any)'] = 'main/index/$1';
Next to this you probably might not want to shift everything onto the index action, but a dynamic action instead. Furthermore, you might want to have a base controller that is delegating everything into the sub-controllers instead of adding the routes per controller. But that's up to you. The example above is based on the directory approach you outlined in your question.
Edit: Additional information is available in the Controllers section next to the URI Routing section
All this seems kind of complicated.
Plus, if you have hundreds (or thousands or more?) of possible routes in a database you may not want to load all of them into the "$routes" array every time any page loads in your application.
Instead, why not just do this?
last line of routes.php:
$route['404_override'] = 'vanity';
Controller file: Vanity.php:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Vanity extends MY_Controller {
/**
* Vanity Page controller.
*
*/
public function __construct() {
parent::__construct();
}
public function index()
{
$url = $_SERVER['PHP_SELF'];
$url = str_replace("/index.php/", "", $url);
// you could check here if $url is valid. If not, then load 404 via:
//
// show_404();
//
// or, if it is valid then load the appropriate view, redirect, or
// whatever else it is you needed to do!
echo "Hello from page " . $url;
exit;
}
}
?>
This situation arises from someone wanting to create their own "pages" in their web site without having to get into creating the corresponding actions.
So say they have a URL like mysite.com/index/books... they want to be able to create mysite.com/index/booksmore or mysite.com/index/pancakes but not have to create any actions in the index controller. They (a non-technical person who can do simple html) basically want to create a simple, static page without having to use an action.
Like there would be some generic action in the index controller that handles requests for a non-existent action. How do you do this or is it even possible?
edit: One problem with using __call is the lack of a view file. The lack of an action becomes moot but now you have to deal with the missing view file. The framework will throw an exception if it cannot find one (though if there were a way to get it to redirect to a 404 on a missing view file __call would be doable.)
Using the magic __call method works fine, all you have to do is check if the view file exists and throw the right exception (or do enything else) if not.
public function __call($methodName, $params)
{
// An action method is called
if ('Action' == substr($methodName, -6)) {
$action = substr($methodName, 0, -6);
// We want to render scripts in the index directory, right?
$script = 'index/' . $action . '.' . $this->viewSuffix;
// Script file does not exist, throw exception that will render /error/error.phtml in 404 context
if (false === $this->view->getScriptPath($script)) {
require_once 'Zend/Controller/Action/Exception.php';
throw new Zend_Controller_Action_Exception(
sprintf('Page "%s" does not exist.', $action), 404);
}
$this->renderScript($script);
}
// no action is called? Let the parent __call handle things.
else {
parent::__call($methodName, $params);
}
}
You have to play with the router
http://framework.zend.com/manual/en/zend.controller.router.html
I think you can specify a wildcard to catch every action on a specific module (the default one to reduce the url) and define an action that will take care of render the view according to the url (or even action called)
new Zend_Controller_Router_Route('index/*',
array('controller' => 'index', 'action' => 'custom', 'module'=>'index')
in you customAction function just retrieve the params and display the right block.
I haven't tried so you might have to hack the code a little bit
If you want to use gabriel1836's _call() method you should be able to disable the layout and view and then render whatever you want.
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
I needed to have existing module/controller/actions working as normal in a Zend Framework app, but then have a catchall route that sent anything unknown to a PageController that could pick user specified urls out of a database table and display the page. I didn't want to have a controller name in front of the user specified urls. I wanted /my/custom/url not /page/my/custom/url to go via the PageController. So none of the above solutions worked for me.
I ended up extending Zend_Controller_Router_Route_Module: using almost all the default behaviour, and just tweaking the controller name a little so if the controller file exists, we route to it as normal. If it does not exist then the url must be a weird custom one, so it gets sent to the PageController with the whole url intact as a parameter.
class UDC_Controller_Router_Route_Catchall extends Zend_Controller_Router_Route_Module
{
private $_catchallController = 'page';
private $_catchallAction = 'index';
private $_paramName = 'name';
//-------------------------------------------------------------------------
/*! \brief takes most of the default behaviour from Zend_Controller_Router_Route_Module
with the following changes:
- if the path includes a valid module, then use it
- if the path includes a valid controller (file_exists) then use that
- otherwise use the catchall
*/
public function match($path, $partial = false)
{
$this->_setRequestKeys();
$values = array();
$params = array();
if (!$partial) {
$path = trim($path, self::URI_DELIMITER);
} else {
$matchedPath = $path;
}
if ($path != '') {
$path = explode(self::URI_DELIMITER, $path);
if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) {
$values[$this->_moduleKey] = array_shift($path);
$this->_moduleValid = true;
}
if (count($path) && !empty($path[0])) {
$module = $this->_moduleValid ? $values[$this->_moduleKey] : $this->_defaults[$this->_moduleKey];
$file = $this->_dispatcher->getControllerDirectory( $module ) . '/' . $this->_dispatcher->formatControllerName( $path[0] ) . '.php';
if (file_exists( $file ))
{
$values[$this->_controllerKey] = array_shift($path);
}
else
{
$values[$this->_controllerKey] = $this->_catchallController;
$values[$this->_actionKey] = $this->_catchallAction;
$params[$this->_paramName] = join( self::URI_DELIMITER, $path );
$path = array();
}
}
if (count($path) && !empty($path[0])) {
$values[$this->_actionKey] = array_shift($path);
}
if ($numSegs = count($path)) {
for ($i = 0; $i < $numSegs; $i = $i + 2) {
$key = urldecode($path[$i]);
$val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null;
$params[$key] = (isset($params[$key]) ? (array_merge((array) $params[$key], array($val))): $val);
}
}
}
if ($partial) {
$this->setMatchedPath($matchedPath);
}
$this->_values = $values + $params;
return $this->_values + $this->_defaults;
}
}
So my MemberController will work fine as /member/login, /member/preferences etc, and other controllers can be added at will. The ErrorController is still needed: it catches invalid actions on existing controllers.
I implemented a catch-all by overriding the dispatch method and handling the exception that is thrown when the action is not found:
public function dispatch($action)
{
try {
parent::dispatch($action);
}
catch (Zend_Controller_Action_Exception $e) {
$uristub = $this->getRequest()->getActionName();
$this->getRequest()->setActionName('index');
$this->getRequest()->setParam('uristub', $uristub);
parent::dispatch('indexAction');
}
}
You could use the magic __call() function. For example:
public function __call($name, $arguments)
{
// Render Simple HTML View
}
stunti's suggestion was the way I went with this. My particular solution is as follows (this uses indexAction() of whichever controller you specify. In my case every action was using indexAction and pulling content from a database based on the url):
Get an instance of the router (everything is in your bootstrap file, btw):
$router = $frontController->getRouter();
Create the custom route:
$router->addRoute('controllername', new Zend_Controller_Router_Route('controllername/*', array('controller'=>'controllername')));
Pass the new route to the front controller:
$frontController->setRouter($router);
I did not go with gabriel's __call method (which does work for missing methods as long as you don't need a view file) because that still throws an error about the missing corresponding view file.
For future reference, building on gabriel1836 & ejunker's thoughts, I dug up an option that gets more to the point (and upholds the MVC paradigm). Besides, it makes more sense to read "use specialized view" than "don't use any view".
// 1. Catch & process overloaded actions.
public function __call($name, $arguments)
{
// 2. Provide an appropriate renderer.
$this->_helper->viewRenderer->setRender('overload');
// 3. Bonus: give your view script a clue about what "action" was requested.
$this->view->action = $this->getFrontController()->getRequest()->getActionName();
}
#Steve as above - your solution sounds ideal for me but I am unsure how you implmeented it in the bootstrap?