Merge pull request #355 from ArthurHoaro/redirector-url
URL encode links when a redirector is set
This commit is contained in:
commit
61873e3ded
10 changed files with 160 additions and 37 deletions
|
@ -57,18 +57,25 @@ class LinkDB implements Iterator, Countable, ArrayAccess
|
||||||
// Hide public links
|
// Hide public links
|
||||||
private $_hidePublicLinks;
|
private $_hidePublicLinks;
|
||||||
|
|
||||||
|
// link redirector set in user settings.
|
||||||
|
private $_redirector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new LinkDB
|
* Creates a new LinkDB
|
||||||
*
|
*
|
||||||
* Checks if the datastore exists; else, attempts to create a dummy one.
|
* Checks if the datastore exists; else, attempts to create a dummy one.
|
||||||
*
|
*
|
||||||
* @param $isLoggedIn is the user logged in?
|
* @param string $datastore datastore file path.
|
||||||
|
* @param boolean $isLoggedIn is the user logged in?
|
||||||
|
* @param boolean $hidePublicLinks if true all links are private.
|
||||||
|
* @param string $redirector link redirector set in user settings.
|
||||||
*/
|
*/
|
||||||
function __construct($datastore, $isLoggedIn, $hidePublicLinks)
|
function __construct($datastore, $isLoggedIn, $hidePublicLinks, $redirector = '')
|
||||||
{
|
{
|
||||||
$this->_datastore = $datastore;
|
$this->_datastore = $datastore;
|
||||||
$this->_loggedIn = $isLoggedIn;
|
$this->_loggedIn = $isLoggedIn;
|
||||||
$this->_hidePublicLinks = $hidePublicLinks;
|
$this->_hidePublicLinks = $hidePublicLinks;
|
||||||
|
$this->_redirector = $redirector;
|
||||||
$this->_checkDB();
|
$this->_checkDB();
|
||||||
$this->_readDB();
|
$this->_readDB();
|
||||||
}
|
}
|
||||||
|
@ -260,6 +267,13 @@ private function _readDB()
|
||||||
// Escape links data
|
// Escape links data
|
||||||
foreach($this->_links as &$link) {
|
foreach($this->_links as &$link) {
|
||||||
sanitizeLink($link);
|
sanitizeLink($link);
|
||||||
|
// Do not use the redirector for internal links (Shaarli note URL starting with a '?').
|
||||||
|
if (!empty($this->_redirector) && !startsWith($link['url'], '?')) {
|
||||||
|
$link['real_url'] = $this->_redirector . urlencode($link['url']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$link['real_url'] = $link['url'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,3 +148,56 @@ function is_session_id_valid($sessionId)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In a string, converts URLs to clickable links.
|
||||||
|
*
|
||||||
|
* @param string $text input string.
|
||||||
|
* @param string $redirector if a redirector is set, use it to gerenate links.
|
||||||
|
*
|
||||||
|
* @return string returns $text with all links converted to HTML links.
|
||||||
|
*
|
||||||
|
* @see Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722
|
||||||
|
*/
|
||||||
|
function text2clickable($text, $redirector)
|
||||||
|
{
|
||||||
|
$regex = '!(((?:https?|ftp|file)://|apt:|magnet:)\S+[[:alnum:]]/?)!si';
|
||||||
|
|
||||||
|
if (empty($redirector)) {
|
||||||
|
return preg_replace($regex, '<a href="$1">$1</a>', $text);
|
||||||
|
}
|
||||||
|
// Redirector is set, urlencode the final URL.
|
||||||
|
return preg_replace_callback(
|
||||||
|
$regex,
|
||||||
|
function ($matches) use ($redirector) {
|
||||||
|
return '<a href="' . $redirector . urlencode($matches[1]) .'">'. $matches[1] .'</a>';
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function inserts where relevant so that multiple spaces are properly displayed in HTML
|
||||||
|
* even in the absence of <pre> (This is used in description to keep text formatting).
|
||||||
|
*
|
||||||
|
* @param string $text input text.
|
||||||
|
*
|
||||||
|
* @return string formatted text.
|
||||||
|
*/
|
||||||
|
function space2nbsp($text)
|
||||||
|
{
|
||||||
|
return preg_replace('/(^| ) /m', '$1 ', $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format Shaarli's description
|
||||||
|
* TODO: Move me to ApplicationUtils when it's ready.
|
||||||
|
*
|
||||||
|
* @param string $description shaare's description.
|
||||||
|
* @param string $redirector if a redirector is set, use it to gerenate links.
|
||||||
|
*
|
||||||
|
* @return string formatted description.
|
||||||
|
*/
|
||||||
|
function format_description($description, $redirector) {
|
||||||
|
return nl2br(space2nbsp(text2clickable($description, $redirector)));
|
||||||
|
}
|
||||||
|
|
48
index.php
48
index.php
|
@ -340,21 +340,6 @@ function logm($message)
|
||||||
file_put_contents($GLOBALS['config']['LOG_FILE'], $t, FILE_APPEND);
|
file_put_contents($GLOBALS['config']['LOG_FILE'], $t, FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In a string, converts URLs to clickable links.
|
|
||||||
// Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722
|
|
||||||
function text2clickable($url)
|
|
||||||
{
|
|
||||||
$redir = empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'];
|
|
||||||
return preg_replace('!(((?:https?|ftp|file)://|apt:|magnet:)\S+[[:alnum:]]/?)!si','<a href="'.$redir.'$1" rel="nofollow">$1</a>',$url);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function inserts where relevant so that multiple spaces are properly displayed in HTML
|
|
||||||
// even in the absence of <pre> (This is used in description to keep text formatting)
|
|
||||||
function keepMultipleSpaces($text)
|
|
||||||
{
|
|
||||||
return str_replace(' ',' ',$text);
|
|
||||||
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
// Sniff browser language to display dates in the right format automatically.
|
// Sniff browser language to display dates in the right format automatically.
|
||||||
// (Note that is may not work on your server if the corresponding local is not installed.)
|
// (Note that is may not work on your server if the corresponding local is not installed.)
|
||||||
|
@ -746,7 +731,8 @@ function showRSS()
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
// Read links from database (and filter private links if user it not logged in).
|
// Read links from database (and filter private links if user it not logged in).
|
||||||
|
|
||||||
|
@ -797,7 +783,9 @@ function showRSS()
|
||||||
// If user wants permalinks first, put the final link in description
|
// If user wants permalinks first, put the final link in description
|
||||||
if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
|
if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
|
||||||
if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
|
if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
|
||||||
echo '<description><![CDATA['.nl2br(keepMultipleSpaces(text2clickable($link['description']))).$descriptionlink.']]></description>'."\n</item>\n";
|
echo '<description><![CDATA['.
|
||||||
|
format_description($link['description'], $GLOBALS['redirector']) .
|
||||||
|
$descriptionlink . ']]></description>' . "\n</item>\n";
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
|
echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
|
||||||
|
@ -835,7 +823,8 @@ function showATOM()
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
|
|
||||||
// Optionally filter the results:
|
// Optionally filter the results:
|
||||||
|
@ -876,7 +865,9 @@ function showATOM()
|
||||||
if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
|
if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
|
||||||
if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
|
if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
|
||||||
|
|
||||||
$entries.='<content type="html"><![CDATA['.nl2br(keepMultipleSpaces(text2clickable($link['description']))).$descriptionlink."]]></content>\n";
|
$entries .= '<content type="html"><![CDATA['.
|
||||||
|
format_description($link['description'], $GLOBALS['redirector']) .
|
||||||
|
$descriptionlink . "]]></content>\n";
|
||||||
if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
|
if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
|
||||||
{
|
{
|
||||||
foreach(explode(' ',$link['tags']) as $tag)
|
foreach(explode(' ',$link['tags']) as $tag)
|
||||||
|
@ -929,7 +920,8 @@ function showDailyRSS() {
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Some Shaarlies may have very few links, so we need to look
|
/* Some Shaarlies may have very few links, so we need to look
|
||||||
|
@ -983,7 +975,7 @@ function showDailyRSS() {
|
||||||
// We pre-format some fields for proper output.
|
// We pre-format some fields for proper output.
|
||||||
foreach ($linkdates as $linkdate) {
|
foreach ($linkdates as $linkdate) {
|
||||||
$l = $LINKSDB[$linkdate];
|
$l = $LINKSDB[$linkdate];
|
||||||
$l['formatedDescription'] = nl2br(keepMultipleSpaces(text2clickable($l['description'])));
|
$l['formatedDescription'] = format_description($l['description'], $GLOBALS['redirector']);
|
||||||
$l['thumbnail'] = thumbnail($l['url']);
|
$l['thumbnail'] = thumbnail($l['url']);
|
||||||
$l['timestamp'] = linkdate2timestamp($l['linkdate']);
|
$l['timestamp'] = linkdate2timestamp($l['linkdate']);
|
||||||
if (startsWith($l['url'], '?')) {
|
if (startsWith($l['url'], '?')) {
|
||||||
|
@ -1016,7 +1008,8 @@ function showDaily()
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
|
|
||||||
$day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
|
$day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
|
||||||
|
@ -1047,7 +1040,7 @@ function showDaily()
|
||||||
$taglist = explode(' ',$link['tags']);
|
$taglist = explode(' ',$link['tags']);
|
||||||
uasort($taglist, 'strcasecmp');
|
uasort($taglist, 'strcasecmp');
|
||||||
$linksToDisplay[$key]['taglist']=$taglist;
|
$linksToDisplay[$key]['taglist']=$taglist;
|
||||||
$linksToDisplay[$key]['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable($link['description'])));
|
$linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $GLOBALS['redirector']);
|
||||||
$linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']);
|
$linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']);
|
||||||
$linksToDisplay[$key]['timestamp'] = linkdate2timestamp($link['linkdate']);
|
$linksToDisplay[$key]['timestamp'] = linkdate2timestamp($link['linkdate']);
|
||||||
}
|
}
|
||||||
|
@ -1107,7 +1100,8 @@ function renderPage()
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
|
|
||||||
$PAGE = new pageBuilder;
|
$PAGE = new pageBuilder;
|
||||||
|
@ -1781,7 +1775,8 @@ function importFile()
|
||||||
$LINKSDB = new LinkDB(
|
$LINKSDB = new LinkDB(
|
||||||
$GLOBALS['config']['DATASTORE'],
|
$GLOBALS['config']['DATASTORE'],
|
||||||
isLoggedIn(),
|
isLoggedIn(),
|
||||||
$GLOBALS['config']['HIDE_PUBLIC_LINKS']
|
$GLOBALS['config']['HIDE_PUBLIC_LINKS'],
|
||||||
|
$GLOBALS['redirector']
|
||||||
);
|
);
|
||||||
$filename=$_FILES['filetoupload']['name'];
|
$filename=$_FILES['filetoupload']['name'];
|
||||||
$filesize=$_FILES['filetoupload']['size'];
|
$filesize=$_FILES['filetoupload']['size'];
|
||||||
|
@ -1932,8 +1927,7 @@ function buildLinkList($PAGE,$LINKSDB)
|
||||||
while ($i<$end && $i<count($keys))
|
while ($i<$end && $i<count($keys))
|
||||||
{
|
{
|
||||||
$link = $linksToDisplay[$keys[$i]];
|
$link = $linksToDisplay[$keys[$i]];
|
||||||
$link['description']=nl2br(keepMultipleSpaces(text2clickable($link['description'])));
|
$link['description'] = format_description($link['description'], $GLOBALS['redirector']);
|
||||||
$title=$link['title'];
|
|
||||||
$classLi = $i%2!=0 ? '' : 'publicLinkHightLight';
|
$classLi = $i%2!=0 ? '' : 'publicLinkHightLight';
|
||||||
$link['class'] = ($link['private']==0 ? $classLi : 'private');
|
$link['class'] = ($link['private']==0 ? $classLi : 'private');
|
||||||
$link['timestamp']=linkdate2timestamp($link['linkdate']);
|
$link['timestamp']=linkdate2timestamp($link['linkdate']);
|
||||||
|
|
|
@ -17,7 +17,7 @@ function hook_qrcode_render_linklist($data)
|
||||||
$qrcode_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.html');
|
$qrcode_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.html');
|
||||||
|
|
||||||
foreach ($data['links'] as &$value) {
|
foreach ($data['links'] as &$value) {
|
||||||
$qrcode = sprintf($qrcode_html, $value['url'], $value['url'], PluginManager::$PLUGINS_PATH);
|
$qrcode = sprintf($qrcode_html, $value['real_url'], $value['real_url'], PluginManager::$PLUGINS_PATH);
|
||||||
$value['link_plugin'][] = $qrcode;
|
$value['link_plugin'][] = $qrcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -511,4 +511,27 @@ public function testFilterFullTextMixed()
|
||||||
sizeof(self::$publicLinkDB->filterFullText('free software'))
|
sizeof(self::$publicLinkDB->filterFullText('free software'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test real_url without redirector.
|
||||||
|
*/
|
||||||
|
public function testLinkRealUrlWithoutRedirector()
|
||||||
|
{
|
||||||
|
$db = new LinkDB(self::$testDatastore, false, false);
|
||||||
|
foreach($db as $link) {
|
||||||
|
$this->assertEquals($link['url'], $link['real_url']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test real_url with redirector.
|
||||||
|
*/
|
||||||
|
public function testLinkRealUrlWithRedirector()
|
||||||
|
{
|
||||||
|
$redirector = 'http://redirector.to?';
|
||||||
|
$db = new LinkDB(self::$testDatastore, false, false, $redirector);
|
||||||
|
foreach($db as $link) {
|
||||||
|
$this->assertStringStartsWith($redirector, $link['real_url']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,4 +187,41 @@ public function testIsSessionIdInvalid()
|
||||||
is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
|
is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test text2clickable without a redirector being set.
|
||||||
|
*/
|
||||||
|
public function testText2clickableWithoutRedirector()
|
||||||
|
{
|
||||||
|
$text = 'stuff http://hello.there/is=someone#here otherstuff';
|
||||||
|
$expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
|
||||||
|
$processedText = text2clickable($text, '');
|
||||||
|
$this->assertEquals($expectedText, $processedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test text2clickable a redirector set.
|
||||||
|
*/
|
||||||
|
public function testText2clickableWithRedirector()
|
||||||
|
{
|
||||||
|
$text = 'stuff http://hello.there/is=someone#here otherstuff';
|
||||||
|
$redirector = 'http://redirector.to';
|
||||||
|
$expectedText = 'stuff <a href="'.
|
||||||
|
$redirector .
|
||||||
|
urlencode('http://hello.there/is=someone#here') .
|
||||||
|
'">http://hello.there/is=someone#here</a> otherstuff';
|
||||||
|
$processedText = text2clickable($text, $redirector);
|
||||||
|
$this->assertEquals($expectedText, $processedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test testSpace2nbsp.
|
||||||
|
*/
|
||||||
|
public function testSpace2nbsp()
|
||||||
|
{
|
||||||
|
$text = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
|
||||||
|
$expectedText = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
|
||||||
|
$processedText = space2nbsp($text);
|
||||||
|
$this->assertEquals($expectedText, $processedText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ function testQrcodeLinklist()
|
||||||
'title' => $str,
|
'title' => $str,
|
||||||
'links' => array(
|
'links' => array(
|
||||||
array(
|
array(
|
||||||
'url' => $str,
|
'real_url' => $str,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -39,7 +39,7 @@ function testQrcodeLinklist()
|
||||||
$link = $data['links'][0];
|
$link = $data['links'][0];
|
||||||
// data shouldn't be altered
|
// data shouldn't be altered
|
||||||
$this->assertEquals($str, $data['title']);
|
$this->assertEquals($str, $data['title']);
|
||||||
$this->assertEquals($str, $link['url']);
|
$this->assertEquals($str, $link['real_url']);
|
||||||
|
|
||||||
// plugin data
|
// plugin data
|
||||||
$this->assertEquals(1, count($link['link_plugin']));
|
$this->assertEquals(1, count($link['link_plugin']));
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="dailyEntryTitle">
|
<div class="dailyEntryTitle">
|
||||||
<a href="{$link.url}">{$link.title}</a>
|
<a href="{$link.real_url}">{$link.title}</a>
|
||||||
</div>
|
</div>
|
||||||
{if="$link.thumbnail"}
|
{if="$link.thumbnail"}
|
||||||
<div class="dailyEntryThumbnail">{$link.thumbnail}</div>
|
<div class="dailyEntryThumbnail">{$link.thumbnail}</div>
|
||||||
|
|
|
@ -70,7 +70,9 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="linktitle"><a href="{$redirector}{$value.url}">{$value.title}</a></span>
|
<span class="linktitle">
|
||||||
|
<a href="{$value.real_url}">{$value.title}</a>
|
||||||
|
</span>
|
||||||
<br>
|
<br>
|
||||||
{if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if}
|
{if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if}
|
||||||
{if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"}
|
{if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"}
|
||||||
|
@ -83,7 +85,7 @@
|
||||||
<span>{$value}</span> -
|
<span>{$value}</span> -
|
||||||
{/loop}
|
{/loop}
|
||||||
|
|
||||||
<a href="{$value.url}"><span class="linkurl" title="Short link">{$value.url}</span></a><br>
|
<a href="{$value.real_url}"><span class="linkurl" title="Short link">{$value.url}</span></a><br>
|
||||||
{if="$value.tags"}
|
{if="$value.tags"}
|
||||||
<div class="linktaglist">
|
<div class="linktaglist">
|
||||||
{loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value}</a></span> {/loop}
|
{loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value}</a></span> {/loop}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div id="picwall_container">
|
<div id="picwall_container">
|
||||||
{loop="linksToDisplay"}
|
{loop="linksToDisplay"}
|
||||||
<div class="picwall_pictureframe">
|
<div class="picwall_pictureframe">
|
||||||
{$value.thumbnail}<a href="{$value.url}"><span class="info">{$value.title}</span></a>
|
{$value.thumbnail}<a href="{$value.real_url}"><span class="info">{$value.title}</span></a>
|
||||||
{loop="$value.picwall_plugin"}
|
{loop="$value.picwall_plugin"}
|
||||||
{$value}
|
{$value}
|
||||||
{/loop}
|
{/loop}
|
||||||
|
|
Loading…
Reference in a new issue