Typoscript: how do I add a parameter to all links in the RTE? - typo3

I want to add a parameter to all links entered in the RTE by the user.
My initial idea was to do this:
lib.parseFunc_RTE.tags.link {
typolink.parameter.append = TEXT
typolink.parameter.append.value = ?flavor=lemon
}
So for example:
http://domain.com/mypage.php
becomes
http://domain.com/mypage.php?flavor=lemon
which sounds great -- as long as the link does not already have a query string!
In that case, I obviously end up with two question marks in the URL
So for example:
http://domain.com/prefs.php?id=1234&unit=moon&qty=300
becomes
http://domain.com/prefs.php?id=1234&unit=moon&qty=300?flavor=lemon
Is there any way to add my parameter with the correct syntax, depending on whether the URL already has a query string or not? Thanks!

That would be the solution:
lib.parseFunc_RTE.tags.link {
typolink.additionalParams = &flavor=lemon
}
Note that it has to start with an &, typo3 then generates a valid link. The parameter in the link also will be parsed with realURL if configured accordingly.
Edit: The above solution only works for internal links as described in the documentation https://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Typolink/Index.html
The only solution that works for all links that I see is to use a userFunc
lib.parseFunc_RTE.tags.link {
typolink.userFunc = user_addAdditionalParams
}
Then you need to create a php script and include in your TS with:
includeLibs.rteScript = path/to/yourScript.php
Keep in mind that includeLibs is outdated, so if you are using TYPO3 8.x (and probably 7.3+) you will need to create a custom extension with just a few files
<?php
function user_addAdditionalParams($finalTagParts) {
// modify the url in $finalTagParts['url']
// $finalTagParts['TYPE'] is an indication of link-kind: mailto, url, file, page, you can use it to check if you need to append the new params
switch ($finalTagParts['TYPE']) {
case 'url':
case 'file':
$parts = explode('#', $finalTagParts['url']);
$finalTagParts['url'] = $parts[0]
. (strpos($parts[0], '?') === false ? '?' : '&')
. 'newParam=test&newParam=test2'
. ($parts[1] ? '#' . $parts[1] : '');
break;
}
return '<a href="' . $finalTagParts['url'] . '"' .
$finalTagParts['targetParams'] .
$finalTagParts['aTagParams'] . '>'
}
PS: i have not tested the actual php code, so it can have some errors. If you have troubles, try debugging the $finalTagParts variable

Test whether the "?" character is already in the URL and append either "?" or "&", then append your key-value pair. There's a CASE object available in the TypoScript Reference, with an example you can modify for your purpose.

For anyone interested, here's a solution that worked for me using the replacement function of Typoscript. Hope this helps.
lib.parseFunc_RTE.tags.link {
# Start by "replacing" the whole URL by itself + our string
# For example: http://domain.com/?id=100 becomes http://domain.com/?id=100?flavor=lemon
# For example: http://domain.com/index.html becomes http://domain.com/index.html?flavor=lemon
typolink.parameter.stdWrap.replacement.10 {
#this matches the whole URL
search = #^(.*)$#i
# this replaces it with itself (${1}) + our string
replace =${1}?flavor=lemon
# in this case we want to use regular expressions
useRegExp = 1
}
# After the first replacement is done, we simply replace
# the first '?' by '?' and all others by '&'
# the use of Option Split allow this
typolink.parameter.stdWrap.replacement.20 {
search = ?
replace = ? || & || &
useOptionSplitReplace = 1
}
}

Related

How would I match the correct hash pair based on a specific string?

I have a simple page hit tracking script that allows for the output to display friendly names instead of urls by using a hash.
UPDATE: I used php to generate the hash below, but used the wrong dynamic page name of item.html. When changed to the correct name, the script returns the desired results. Sorry for wasting anyone's time.
my %LocalAddressTitlePairs = (
'https://www.mywebsite.com/index.html' => 'HOME',
'https://www.mywebsite.com/art_gallery.html' => 'GALLERY',
'https://www.mywebsite.com/cart/item.html?itemID=83&cat=26' => 'Island Life',
'https://www.mywebsite.com/cart/item.html?itemID=11&cat=22' => 'Castaways',
'https://www.mywebsite.com/cart/item.html?itemID=13&cat=29' => 'Pelicans',
and so on..
);
The code for returning the page hits:
sub url_format {
local $_ = $_[0] || '';
if ((m!$PREF{'My_Web_Address'}!i) and (m!^https://(.*)!i) ) {
if ($UseLocalAddressTitlePairs == 1) {
foreach my $Address (keys %LocalAddressTitlePairs) {
return "<a title=\"$Address\" href=\"$_\">$LocalAddressTitlePairs{$Address}</A>" if (m!$_$! eq m!$Address$!);
}
}
my $stub =$1;
return $stub;
}
}
Displaying the log hits will show
HOME with the correct link, GALLERY with the correct url link, but https://www.mywebsite.com/cart/item.html?itemID=83&cat=26
will display a random name instead of what it should be, Island Life for this page.. it has the correct link,-- a different name displays every time the page is loaded.
And, the output for all pages with query strings will display the exact same name. I know the links are correct by clicking thru site pages and checking the log script for my own page visits.
I tried -
while (my($mykey, $Value) = each %LocalAddressTitlePairs) {
return "<a title=\"$mykey\" href=\"$_\">$Value</a>" if(m!$_$! eq m!$mykey$!);
but again, the link is correct but the mykey/Value associated is random too. Way too new to perl to figure this out but I'm doing a lot of online research.
m!$Address$! does not work as expected, because the expression contains special characters such as ?
You need to add escape sequences \Q and \E
m!\Q$Address\E$!
it’s even better to add a check at the beginning of the line, otherwise
my $url = "https://www.mywebsite.com/?foo=bar"
my $bad_url = "https://bad.com?u=https://www.mywebsite.com/?foo=bar"
$bad_url =~ m!\Q$url\E$! ? 1 : 0 # 1, pass
$bad_url =~ m!^\Q$url\E$! ? 1 : 0 # 0, fail

Is there an easy way to add/remove/modify query parameters of a URL in Tritium?

I saw a very manual way of doing this in another post: How do I add a query parameter to a URL?
This doesn't seem very intuitive, but someone there mentioned an easier way to accomplish this using the upcoming "URL scope". Is this feature out yet, and how would I use it?
If you're using the stdlib mixer, you should be able to use the URL scope which provides helper functions for adding, viewing, editing, and removing URL params. Here's a quick example:
$original_url = "http://cuteoverload.com/2013/08/01/buttless-monkey-jams?hi=there"
$new_url = url($original_url) {
log(param("hi"))
param("hello", "world")
remove_param("hi")
}
log($new_url)
Tritium Tester example here: http://tester.tritium.io/9fcda48fa81b6e0b8700ccdda9f85612a5d7442f
Almost forgot, link to docs: http://tritium.io/current (You'll want to click on the URL category).
AFAIK, there's no built-in way of doing so.
I'll post here how I did to append a query param, making sure that it does not get duplicated if already on the url:
Inside your functions/main.ts file, you can declare:
# Adds a query parameter to the URL string in scope.
# The parameter is added as the last parameter in
# the query string.
#
# Sample use:
# $("//a[#id='my_link]") {
# attribute("href") {
# value() {
# appendQueryParameter('MVWomen', '1')
# }
# }
# }
#
# That will add MVwomen=1 to the end of the query string,
# but before any hash arguments.
# It also takes care of deciding if a ? or a #
# should be used.
#func Text.appendQueryParameter(Text %param_name, Text %param_value) {
# this beautiful regex is divided in three parts:
# 1. Get anything until a ? or # is found (or we reach the end)
# 2. Get anything until a # is found (or we reach the end - can be empty)
# 3. Get the remainder (can be empty)
replace(/^([^#\?]*)(\?[^#]*)?(#.*)?$/) {
var('query_symbol', '?')
match(%2, /^\?/) {
$query_symbol = '&'
}
# first, it checks if the %param_name with this %param_value already exists
# if so, we don't do anything
match_not(%2, concat(%param_name, '=', %param_value)) {
# We concatenate the URL until ? or # (%1),
# then the query string (%2), which can be empty or not,
# then the query symbol (either ? or &),
# then the name of the parameter we are appending,
# then an equals sign,
# then the value of the parameter we are appending
# and finally the hash fragment, which can be empty or not
set(concat(%1, %2, $query_symbol, %param_name, '=', %param_value, %3))
}
}
}
The other features you want (remove, modify) can be achieved similarly (by creating a function inside functions/main.ts and leveraging some regex magic).
Hope it helps.

TYPO3: Parse current url into variable

i know how i get the current URL with typoscript, but i dont know how i can parse this url into a variable so i can use and work with it.
temp.getUrl = TEXT
temp.getUrl.typolink {
parameter.data=TSFE:id
returnLast=url
}
This example returns me an url segment like 'This/is/just/a/test.html', so long – perfect!
Now i try to save this url into an Variable like
temp.getUrl = TEXT
temp.getUrl.typolink {
parameter.data=TSFE:id
returnLast=url
}
wiredMindsCompleteUrl < temp.getUrl
This results everytime just with 'TEXT' :( i kinda depressed.
Please help :)
The question is, where do you want to use it.
If you want to use it in different places in TypoScript you can f.e. render it into stdWrap.append / stdWrap.prepend of your links.
myMenu = HMENU
myMenu ...
myMenu.stdWrap.append < temp.getUrl
You could just put it into an Register:
page.1.LOAD_REGISTER
page.1.getUrl < temp.getUrl
and f.e. use your register in the tilte-Tag of an image:
lib.MyImage = IMAGE
lib.MyImage.file = ...
lib.MyImage.titleText.data = REGISTER:getUrl
lib.MyImage.tilteText.noTrimWrap = | makes no sense (IMHO:) ||
If you need it in your extension, just use it with cObjGetSingle.
plugin.tx_yourextension_pi1.getUrl < temp.getUrl
Inside your extension use it via
function main($content, $conf) {
$this->conf = $conf;
return $this->cObj->cObjGetSingle($this->conf['getUrl'], $this->conf['getUrl.'], 'getUrl');
}
Side note: use lib.getUrl instead of temp.getUrl, otherwise you can get in trouble with non-cached TypoScript parts.

Facing Issue in zend_search_lucene

I am using Zend Lucene Search:
......
$results = $test->fetchAll();
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
foreach ($results as $result) {
$doc = new Zend_Search_Lucene_Document();
// add Fields
$doc->addField(
Zend_Search_Lucene_Field::Text('testid', $result->id));
$doc->addField(
Zend_Search_Lucene_Field::Keyword('testemail', strtolower(($result->email))));
$doc->addField(
Zend_Search_Lucene_Field::Text('testconfirmdate', $result->confirmdate));
$doc->addField(
Zend_Search_Lucene_Field::Text('testcreateddate', $result->createddate));
// Add document to the index
$index->addDocument($doc);
}
// Optimize index.
$index->optimize();
// Search by query
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
if(strlen($Data['name']) > 2){
//$query = Zend_Search_Lucene_Search_QueryParser::parse($Data['name'].'*');
$pattern = new Zend_Search_Lucene_Index_Term($Data['name'].'*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$this->view->hits = $index->find(strtolower($query));
}
else{
$query = $Data['name'];
$this->view->hits = $index->find($query);
}
............
Works fine here:
It works when I give complete word, first 3 character, case insensitive words
My issues are:
When I search for email, i got error like "Wildcard search is supported only for non-multiple word terms "
When I search for number/date like "1234" or 09/06/2011, I got error like "At least 3 non-wildcard characters are required at the beginning of pattern"
I want to search date, email, number here.
In file zend/search/Lucene/search/search/query/wildcard a parameter is set,
private static $_minPrefixLength = 3;
chnage it and it may work..!
Based on NaanuManu's suggestion, I did a little more digging to figure this out - I posted my answer on a related question here, but repeating for convenience:
Taken directly from the Zend Reference documentation, you can use:
Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() to
query the minimum required prefix length and
use Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength() to
set it.
So my suggestion would be either of two things:
Set the prefixMinLength to 0 using Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(0)
Validate all search queries using javascript or otherwise to ensure there is a minimum of Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() before any wildcards used (I recommend querying that instead of assuming the default of "3" so the validation is flexible)

How should I redirect users in a formmail script?

So I'm using a basic formmail script. Within the script I'm using a redirect variable. The value of the redirect is something like:
http://www.mysite.com/NewOLS_GCUK_EN/bling.aspx?BC=GCUK&IBC=CSEE&SIBC=CSEE
When the redirect action happens however, the URL appears in the browser as:
http://www.mysite.com/NewOLS_GCUK_EN/bling.aspx?BC=GCUK&IBC=CSEE&SIBC=CSEE
You can see the & characters are replaced with &
Is there any way to fix this?
Maybe you can edit the script with a string substitution:
$myRedirectURL =~ s/\&/\&/g;
Or perhaps look in the script where the opposite substitution is taking place, and comment out that step.
HTML::Entities's decode_entities could decode this for you:
$redirect_target = decode_entities($redirect_target);
But passing the destination URL as HTTP argument (e.g. hidden form field) is dangerous (as #Sinan Ünür already said in the comments). Better store the target URL within your script and pass a selector from the form:
if ($selector eq 'home') { $target_url = 'http://www.foo.bar/'; }
elsif ($selector eq 'bling') { $target_url = 'http://www.foo.bar/NewOLS_GCUK_EN/bling.aspx'; }
else {
$target_url = 'http://www.foo.bar/default.html'; # Fallback/default value
}
Using a Hash would be shorter:
my %targets = {
home => 'http://www.foo.bar/',
bling => '/NewOLS_GCUK_EN/bling.aspx',
};
$target_url = $targets{$selector} || '/default_feedback_thanks.html';