May 22, 2008

Linking properly in your TYPO3 code

Recently I often see that TYPO3 plugins do not create links properly. It seems that authors simply do not know how to make links properly in TYPO3. As a result links are not RealURL-compatible or cache issues happen.

This article shows how to use typoLink in Frontend plugin.


To create a link from plugin you can either use one of pi_* functions available from tslib_pibase class or use tslib_cObj::typoLink function. The first is good if you need to keep and/or replace plugin variables. The second one is the most universal and I want to focus on it in this article.
The first thing you should have under hand before you start using typoLink is... TSRef. Yes, TypoScript reference. It contains full description of typoLink configuration.
When using typoLink, there are several important properties, to which you need pay special attention:
  • useCacheHash
    If URL contains any parameters that affect page content and that content iscached (=not produced by USER_INT plugin), then URL must include cHash. cHash ensures that page cache takes URL parameters into account. If you forget cHash for cached content, you will get the same content every time with different parameters.
  • additionalParams
    Firsts, it must start with & character. If not, it will be ignored. Secodnly, it is sdWrap, which gives you great flexibility for adding parameters.
  • no_cache
    Generally this must not be set because it makes performance of the web server zero.
typoLink is usually called in the following way:

$link = $this->cObj->typoLink('linkedText', $conf);

This will create a complete link: text linked to whatever specified in configuration. It is possible to get only link by using typoLink_URL instead. There is also configuration option that forces typoLink to return URL.

Full code example for typoLink with explanation:

$conf = array(
  // Link to current page
  'parameter' => $GLOBALS['TSFE']->id,
  // Set additional parameters
  'additionaParams' => '&tx_ttnews[tt_news]=' . $ttNewsItemUid,
  // We must add cHash because we use parameters
  'useCashHash' => true,
  // We want link only
  'returnLast' => 'url',
);
$url = $this->cObj->typoLink('', $conf);

As you see, it is very easy to use typoLink. As additional bonus you get simulateStatic/RealURL/CoolURI automatically.

18 comments:

  1. Thanks for good article.

    But, it says nothing about good practices for customizing links.

    f.e. if I need to insert class=\"link-to-single\" to every link that points to single item (news, gallery, faq ...).

    I have some solutions for this problem

    1) Use TS configuration for plugin. I use code like this

    plugin.tx_myplugin {

    linkToSingle {

    parameter = single

    ATagParams = class=\"link-to-single\"

    }

    }



    And than in my PHP code:



    singleTypolinkConf = $this->conf[\'linkToSingle.\'];

    singleTypolinkConf[\'additionalParams\'] .= \'&singleUid=\'.$singleUid;

    $link = explode(\'|\',$this->cObj->typoLink(\'|\', $singleTypolinkConf)); //Use this as wrap subpart



    But I do not think this method is good enough.

    I can\'t predict what will happend if someone will use returnLast=url in TS setup (for customization).



    Can you me how to handle with problems of customization of links.

    Thanks.

    ReplyDelete
  2. Well, if you are afraid of returnLast, you always can unset it.

    ReplyDelete
  3. Hi Dmitry,



    great article that sums up nicely the essentials of link building in TYPO3.



    Just to make sure, people won\'t fail in generating links when using the above code:



    There is a misspelling in the PHP typolink code. The parameters name is \"useCacheHash\", not \"useCashHash\"... or do you also take credit cards? ;))



    Big ups from Germany,

    Jochen

    ReplyDelete
  4. I think, there is a typo:



    additionaParams -> should be -> additionalParams



    Thanks for your blog!





    Stefan.

    ReplyDelete
  5. Dear Dmitry,

    many thanks for your clear thinking, your inspiring articles and your book. :-)



    Can you give me a hint to the following problem.



    If there is an address extension, where you can filter the zip-code lists:

    e.g. test.com/address/zip/20-29.html (realURL) or test.com/address.html?tx_list_pi1[zip]=20-29



    Without filter-parameters there is no problem to get the result cached.

    But is it possible to get the result-pages with filter-parameters into cache, even the result-pages are called with EXTERNAL links?



    ['enableCHashCache' => true] in realURL seems not to be enough. Is it possible to use some sort of general ['useCashHash' => true] ?



    That would be great.

    ReplyDelete
  6. Hi, Dmitry,



    I generate some email messages in Backend module and use there tslib_cObj a lot. What if I want to print in that emails full links (with host)? Maybe it will be good to add a function 'fullURL' to typolink?



    What do you think?

    Thank you.

    ReplyDelete
  7. back to my question from 17-03-09. If my wish comes true, there would be snakes in paradise:

    http://typo3.org/development/articles/the-mysteries-of-chash/

    »What if someone requests 1 million URLs with random parameters like “?id=123&USELESS_PARAMETER=[any random number]” - that would spam our database with gigabytes of cached instances of... the SAME page!«

    ReplyDelete
  8. Thanks for the tip, Dmitry!



    As Jochen and Stefan pointed out earlier, there are two spelling mistakes in the example code, it should read:



    $conf = array(

    // Link to current page

    'parameter' => $GLOBALS['TSFE']->id,

    // Set additional parameters

    'additionalParams' => '&tx_ttnews[tt_news]=' . $ttNewsItemUid,

    // We must add cHash because we use parameters

    'useCacheHash' => true,

    // We want link only

    'returnLast' => 'url',

    );

    $url = $this->cObj->typoLink('', $conf);

    ReplyDelete
  9. hello!!



    I wish to know a few details about TYPO3. Specifically about its coding practices.



    • Version

    • If code indentation is changed, will it change the code

    • if we break a line of code, do we need to insert a special character at the end:

    • Is the technology case sensitive

    • Is there any preference of space for code indentation

    • Will the opening braces appear at the end of the same line as the declaration statement after a space or on a new line

    • Example code

    ReplyDelete
  10. Hi Dmitry,



    I know you are a very busy man, but it'd be nice to fix the 2 typos in the code of your article as mentioned in the comments above (additionalParams + useCacheHash). I personnaly lost a couple of hours because of those...



    I count among those developers not having been able to make a correct typolink for years. So far, I have been developing about 10 extensions, but could not figure which was the correct typolink function to use. That is because there exist 14 linking functions split over 2 classes, and typolink isn't even included in tslib_pibase which is used to inherit frontend plugins classes !

    I guess it was about time to move to a new codebase. My hope is typo3 5.0 will only have 1 linking function !

    ReplyDelete
  11. One weird thing about typolink is if you want to include the parameter &type=custom_page_type in 'additionalParams' it won't work.



    To use a page type, one must use a coma and add the type value behind the page uid in 'parameter' :



    $conf = array(

    // Link to current page

    'parameter' => $GLOBALS['TSFE']->id.','.$custom_page_type, //<- page type goes here

    'additionalParams' => '&tx_ttnews[tt_news]=' . $ttNewsItemUid,

    'useCacheHash' => true,

    'returnLast' => 'url',

    );

    ReplyDelete
  12. Hi,



    why Im getting 0 in my url ? like ....com/ponudba/0/sri-lanka/?no_cache=1



    My RealURL conf is this http://pastebin.com/m321dc60c



    I dont have any other params, just program_id and thats it. I dont know from where it takes 0...



    If anybody can give me any tip what Im doing wrong... I would be really happy ;)

    ReplyDelete
  13. Hi, Dmitry!



    How to build links properly in AJAX calls?

    ReplyDelete
  14. Dimitry, you saved my Day! Thank you very much :)

    ReplyDelete
  15. Hi Dimitry!!

    awesome!!

    your are my savior.

    ReplyDelete
  16. additionalParams not additionaParams

    ReplyDelete
  17. Thanks so much, you've saved my day!

    ReplyDelete
  18. Hi,

    you forgot to mention where to give target="_blank"

    ReplyDelete