7

I have an extension with a list and show action. Currently this extension can appear on multiple pages:

/page-1/
/page-2/subpage/

I have configured realurl like that:

$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']=array (
    'encodeSpURL_postProc' => array('user_encodeSpURL_postProc'),
    'decodeSpURL_preProc' => array('user_decodeSpURL_preProc'),
    '_DEFAULT' => array (
        …
        'postVarSets' => array(
            '_DEFAULT' => array(
                'controller' => array(
                    array(
                        'GETvar' => 'tx_extension_plugin[controller]',
                        'noMatch' => 'bypass',
                    ),
                ),
                'extension' => array(
                    array(
                        'GETvar' => 'tx_extension_plugin[action]',
                    ),
                    array(
                        'GETvar' => 'tx_extension_plugin[controller]',
                    ),
                    array(
                        'GETvar' => 'tx_extension_plugin[value]',
                        'lookUpTable' => array(
                            'table' => 'table',
                            'id_field' => 'uid',
                            'alias_field' => 'name',
                            'addWhereClause' => ' AND NOT deleted AND NOT hidden',
                            …
);

function user_decodeSpURL_preProc(&$params, &$ref) {
    $params['URL'] = str_replace('page-1/', 'page-1/extension/', $params['URL']);
}

function user_encodeSpURL_postProc(&$params, &$ref) {
    $params['URL'] = str_replace('page-1/extension/', 'page-1/', $params['URL']);
}

Now I get URLs like:

/page-1/ /* shows list */
/page-1/Action/show/name-of-single-element /* single view */

What I actually want is this:

/page-1/name-of-single-element /* single view */

How do I get rid of the action and controller?

If I remove:

array('GETvar' => 'tx_extension_plugin[action]'),
array('GETvar' => 'tx_extension_plugin[controller]'),

it appends the parameters to the URL.

lampshade
  • 2,470
  • 3
  • 36
  • 74
  • 1
    It requires another approach, is it your extension ? can you change it's code? show me how do you build your links/urls – biesior Oct 01 '14 at 14:37
  • @biesior Yes, it's my own extension and yes, I can change everything. The links are build like this: `show article` – lampshade Oct 01 '14 at 14:57

2 Answers2

7

You can't avoid adding all the stuff when using f:link.action VH, instead you need to use f:link.page and pass only required params, sample:

<f:link.page additionalParams="{article : article.uid}" class="more" title="{article.name}">show article</f:link.page>

it will generate url like

/current/page/?article=123

or

/current/page/we-added-realurl-support-for-article

next in your first action of plugin (probably list) you just need to forward request to show action if given param exists:

public function listAction() {
    if (intval(\TYPO3\CMS\Core\Utility\GeneralUtility::_GET('article'))>0) $this->forward('show');

    // Rest of code for list action...
}

and probably change signature of show

public function showAction() {

    $article = $this->articleRepository->findByUid(intval(\TYPO3\CMS\Core\Utility\GeneralUtility::_GET('article')));

    if ($article == null) {
        $this->redirectToUri($this->uriBuilder->reset()->setTargetPageUid($GLOBALS['TSFE']->id)->build());
    }


    // Rest of code for show action...
}
Urs
  • 4,984
  • 7
  • 54
  • 116
biesior
  • 55,576
  • 10
  • 125
  • 182
  • 1
    +1 - works like a charm. Thanks a lot. I changed the code a bit to make it more versatile. I changed the signature to: `public function showAction(\namespace $article = null)` and wrapped the newly added part into this: `if (!$article) { … }`. – lampshade Oct 06 '14 at 09:29
  • I am using an @transient property in my extension (see http://stackoverflow.com/questions/27274477/parse-an-existing-json-string-in-fluid-template) - can it be that it fails with the above method? When I got it working, all that "transient" data wasn't output anymore – Urs Jan 08 '15 at 17:52
  • Seems that extbase was less strict towards the type of property (which I had set wrong) when using the "action" link than now with the alternative procedure. It had nothing to do with "transient" – Urs Jan 08 '15 at 19:25
  • That solution works really good. Thank you very much, in some cases it might be better to use the standard get variables like tx_yourext['article'] – Florian Rachor May 13 '15 at 14:53
  • 1
    This answer is violating the aspects of domain-driven design and separation of concerns in may ways. Each action shall be called directly with the accordant and valid set of arguments - this is the job of the request-handler, not the job of any controller logic. By-passing the request/response separation and fetching GET parameters directly is another violation - and dangerous in terms of working with non-validated user submitted data (SQLi, XSS et al). Even if it works, it's still hacky... – Oliver Hader Oct 14 '16 at 15:46
7

If the URIbuilder is used you can also use the configuration:

features.skipDefaultArguments = 1

for example;

# if enabled, default controller and/or action is skipped when creating URIs through the URI Builder 
plugin.tx_extension.features.skipDefaultArguments = 1

I use this configuration in combination with the realurl bypass

'postVarSets' => array(
  '_DEFAULT' => array(
    'extbaseParameters' => array(
      array(
        'GETvar' => 'tx_extension_plugin[action]',
        'noMatch' => 'bypass',
      ),
    ),
  ),
),
Aleksandr M
  • 24,264
  • 12
  • 69
  • 143