I have a controller with an action and a variable like this:
class AccountsController extends AppController
{
function profile($username = null)
{
}
}
The url for this page is:
[domain]/accounts/profile/[username]
How do I make it:
[domain]/[username]
?
Try:
//in your routes.php file
Router::connect('/:username',
array('controller' => 'accounts', 'action' => 'profile'),
array(
'pass' => array('username')
)
);
Hope it helps
Related
Is it possible to have a localization based on RealURL's valueMap static table ?
For example, in Deutsch language, I have www.example.com/de/account/produktinfos/
de/ is language
account/ page
produktinfos/ controller action
And what I need is to translate the produktinfos/part to English, i.e., www.example.com/en/account/productinfo/.
Is there a way to translate the controller action in RealURL?
I don't know if this help for you.
You can use some realurl post/pre Procs.
for example:
// realurl Hook for replacing some path
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = array(
'encodeSpURL_postProc' => array('user_encodeSpURL_postProc'),
'decodeSpURL_preProc' => array('user_decodeSpURL_preProc')
);
and replace controller action in URL
function user_encodeSpURL_postProc(&$params, &$ref) {
$params['URL'] = str_replace('job/job/Job/show/', 'job/', $params['URL']);
}
function user_decodeSpURL_preProc(&$params, &$ref) {
$params['URL'] = str_replace('job/', 'job/job/Job/show/', $params['URL']);
}
the blog post
https://www.kartolo.de/2014/11/21/extbase-and-realurl/
An other solution can be like that?
// news pagebrowser
'my-action' => array(
array(
'GETvar' => 'tx_myext[action]',
'valueMap' => array(
preg_match('%/de/%',$_SERVER['REQUEST_URI'])==1?'anzeigen':'show' => 'show',
)
),
),
I want to create an url with this format :
domain.com/list?sortBy=number&sortDir=desc
in my View (blade). I'm using this approach which I don't really prefered :
{{ url("list")."?sortBy=".$sortBy."&sortDir=".$sortDir }}
because using
{{ url("list", $parameters = array('sortBy' => $sortBy, 'sortDir' => $sortDir) }}
didn't produce as I hoped. Is there a better way?
Have you tried the URL::route method.
Example Route:
Route::get('/list', array('as' => 'list.index', 'uses' => 'ListController#getIndex'));
Retrieve the URL to a specific route with query string:
URL::route('list.index', array(
'sortBy' => $sortBy,
'sortDir' => $sortDir
));
If your using a closure on the route:
Route::get('/list', array('as' => 'list.index', function()
{
return URL::route('account-home', array(
'sortBy' => 1,
'sortDir' => 2
));
}));
I have the code to change the language of site. I would like to extend this functional. I want to make sure that the language parameter in the url is correct when I get the 404 page (or dispatch_error event).
My route example
'about' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:lang/]about',
'constraints' => array(
'lang' => '[a-zA-Z]{2}?',
),
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'about',
'lang' => 'en',
),
),
),
If url param isn't correct (example.com/e/about or exampleDotcom//about), then makes redirect to the specific page (for example, example.com/why_did_it_happen). To make this, I create a function checkRedirect and attach it to EVENT_DISPATCH_ERROR . But how to get the LANG parameter from the url and then make a redirect, I don't know. I tried to do this many times, but could not. I've got - Call to a member function getParam () on a non-object. What code would I append to the checkRedirect function to get the LANG parameter from the url and then make a redirect in this function?
My code in Module.php
class Module implements
AutoloaderProviderInterface,
ConfigProviderInterface,
ViewHelperProviderInterface {
public function onBootstrap(MvcEvent $e) {
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'initLocale'), -100);
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'checkRedirect'), -101);
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 100);
}
public function initLocale(MvcEvent $e) {
$translator = $e->getApplication()->getServiceManager()->get('translator');
$config = $e->getApplication()->getServiceManager()->get('Config');
$shotLang = $e->getRouteMatch()->getParam('lang'); //or $e->getApplication()->getMvcEvent()->getRouteMatch();
if (isset($config['languages'][$shotLang])) {
$translator->setLocale($config['languages'][$shotLang]['locale']);
} else {
$lang = array_shift($config['languages']);
$translator->setLocale($lang['locale']);
}
}
public function checkRedirect(MvcEvent $e) {
//code here
}
$e->getRouteMatch()->getParam('NAME')
This does work, but 'NAME', but be the name given in the routes.
'route' => '/[:lang/]about',
However, the above route does not match the route *example.com/why_did_it_happen*
Try changing your route to
'route' => '[/:lang]/about',
And you could always default, if a lang is not supplied, i.e.
$e->getRouteMatch()->getParam('lang', 'en');
In my project I have a navigation, which is created from an array in a config.php file using the default factory. I want to add subpages to the current pages in the controller.
class IndexController extends AbstractActionController {
public function newpageAction() {
$navigation = $this->getServiceLocator()->get('navigation');
$currentPage = $navigation->findById('index');
$options = array(
'id' => 'newpage',
'label' => 'New Page',
'route' => 'my-route',
'controller' => 'index',
'action' => 'newpage',
'active' => true,
);
$newpage = new \Zend\Navigation\Page\Mvc($options);
$currentPage->addPage($newpage);
}
}
The page is added successfully but then I try to create the url for the page in the breadcrumbs view using the getHref() method of the page:
<?php foreach($this->pages as $page) {?>
<li>
<?php echo $page->getLabel();?>
</li>
<?php }?>
But I get the following error for the newly added pages:
Additional information:
Zend\Navigation\Exception\DomainException
File:
\vendor\zendframework\zendframework\library\Zend\Navigation\Page\Mvc.php:198
Message:
Zend\Navigation\Page\Mvc::getHref cannot execute as no Zend\Mvc\Router\RouteStackInterface instance is composed
I guess the problem is in the way I create and add the pages to the navigation. Is there another way to do that or how I fix this error?
I want to add the pages after the 3th level in the controller instead of in the config file because there are params in the urls of the pages and the labels are dynamic.
Any suggestions for accomplishing this task in any other way are welcome.
You could add the default router.
\Zend\Navigation\Page\Mvc::setDefaultRouter ($this->getServiceLocator ()->get ('router'));
The error is due to the MVC page having unmet dependencies (the router). It is the factory's job to inject these components (depending on a URI or MVC type).
To make sure each MVC page has router injected create a new factory that in turn uses another already provided factory Zend\Navigation\Service\ConstructedNavigationFactory to create your own navigation container and return it's pages. In your example this will be just one page.
EDIT
If you have to add the navigation pages in the controller, where you do not know the page config prior to the newpageAction(); You could extend the class to allow config to be set within the controller.
For example
public function MyCustomNavFactory extends ConstructedNavigationFactory
{
// make the config optional
public function __construct($config = array())
{
$this->config = $config;
}
// Allow config to be set outside the class
public function setConfig($config)
{
$this->config = $config;
}
}
Module.php
// Module
public function getServiceConfig() {
return array(
'invokables' => array(
// Create the factory as an invokable (as there are no __construct args)
'MyCustomNavFactory' => 'App\Navigation\Service\MyCustomNavFactory'
),
);
}
The controller call would then just be simply just use
// Controller
public function newpageAction()
{
$serviceManager = $this->getServiceLocator();
$navigation = $serviceManager->get('MyCustomNavFactory');
$options = array(
'id' => 'newpage',
'label' => 'New Page',
'route' => 'my-route',
'controller' => 'index',
'action' => 'newpage',
'active' => true,
);
$navigation->setConfig($options);
$pages = $navigation->getPages($serviceManager);
}
The answer of #AlexP is correct.
But there error into Controller Action As when he call custom factory using ServiceLocator will get Object of type AbstractContainer Object Because ServiceLocator will call createService method into your custom factory (MyCustomNavFactory) which extends AbstractNavigationFactory So the next line will call setConfig method into AbstractContainer Object not into your custom factory (MyCustomNavFactory).
The correct Way to Set Breadcrumb configuration from Controller Action is:
// Controller
public function newpageAction()
{
$serviceManager = $this->getServiceLocator();
$navigationFactory = new MyCustomNavFactory();
$options = array(
'id' => 'newpage',
'label' => 'New Page',
'route' => 'my-route',
'controller' => 'index',
'action' => 'newpage',
'active' => true,
);
$navigationFactory->setConfig($options);
$pages = $navigationFactory->getPages($serviceManager);
}
OR
Remove setConfig method form custom factory and set configuration using it's Constructor
// custom Factory
public function MyCustomNavFactory extends ConstructedNavigationFactory
{
// make the config optional
public function __construct($config = array())
{
parent::__construct($config);
}
}
Then Controller will be:
// Controller
public function newpageAction()
{
$serviceManager = $this->getServiceLocator();
$options = array(
array(
'id' => 'newpage',
'label' => 'New Page',
'route' => 'my-route',
'controller' => 'index',
'action' => 'newpage',
'active' => true,
)
);
$navigationFactory = new MyCustomNavFactory($options);
$pages = $navigationFactory->getPages($serviceManager);
}
I need to forward the ajax request to the other Action method of current controller. I use the Forward plugin but it doesn't work. There is an example in the manual about how to use the Forward Plugin:
$foo = $this->forward()->dispatch('foo', array('action' => 'process'));
return array(
'somekey' => $somevalue,
'foo' => $foo,
);
My code:
// From Ajax on the page. I apply to the indexAction of FooController,
// I use RegEx route
xhr.open('get', '/fooindex', true);
// My Controller
namespace Foo\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
// I extend the AbstractActionController, the manual says it's important for the Forward Plugin to work
class FooController extends AbstractActionController {
// This is the action I send my request from Ajax
public function indexAction() {
// if the request if Ajax request I forward the run to the nextAction method
if ($this->getRequest()->isXmlHttpRequest()) {
// I do as manual says
$rs = $this->forward()->dispatch('FooController', array('action' => 'next'));
}
}
public function nextAction() {
// And I just want to stop here to see that the Forward Plugin works
// But control doesn't reach here
exit('nextAction');
}
}
The error I get in the Console is:
GET http://test.localhost/fooindex 500 (Internal Server Error)
If I do not use Forward everything works fine, the request comes to the indexAction just fine. Only Forward throws an error.
From the manual, about The Forward Plugin:
For the Forward plugin to work, the controller calling it must be
ServiceLocatorAware; otherwise, the plugin will be unable to retrieve
a configured and injected instance of the requested controller.
From the manual, about Available Controllers:
Implementing each of the above interfaces is a lesson in redundancy;
you won’t often want to do it. As such, we’ve developed two abstract,
base controllers you can extend to get started.
AbstractActionController implements each of the following interfaces:
Zend\Stdlib\DispatchableInterface
Zend\Mvc\InjectApplicationEventInterface
Zend\ServiceManager\ServiceLocatorAwareInterface
Zend\EventManager\EventManagerAwareInterface
So my FooController extends AbstractActionController, which implements ServiceLocatorAwareInterface, so the Forward has to work, but it doesn't. What did I miss? How to make it work?
You should remember that the dispatch plugin gets the controller to dispatch to from the service manager by name. You should therefore use the correct name and not just the classname.
Look in your configuration for the controllers.invokables array. That should contain which name of the service maps to what FQCN.
It might be you name IS FooController, then forget what I just said
You should use fully qualified name when calling the controller, so 'FooController' should be namespaced as well.
Also, you should add the controller in the list of the invokables in the module config files, for example:
return array(
'controllers' => array(
'invokables' => array(
'FooController' => 'Namespace/Controller/FooController'
...
),
)
)
try this:
class FooController extends AbstractActionController {
public function indexAction() {
return $this->forward()->dispatch('Bar\Controller\Bar',
array(
'action' => 'process',
'somekey' => $somevalue,
));
}
}
here invokable is: 'Bar\Controller\Bar' => 'Bar\Controller\Bar'
try this:
class FooController extends AbstractActionController {
public function indexAction() {
return $this->forward()->dispatch('Foo',
array(
'action' => 'process',
'somekey' => $somevalue,
));
}
}
Your module.config.php file is like this:
'controllers' => array(
'invokables' => array(
'Foo' => 'Foo\Controller\FooController', // <----- Module Controller
),
),
'router' => array(
'routes' => array(
'foo' => array(
'type' => 'segment',
'options' => array(
'route' => '/foo[/:action][/:id]', // <---- url format module/action/id
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Foo', // <--- Defined as the module controller
'action' => 'index', // <---- Default action
),
),
),
),
),