News:

Wondering if this will always be free?  See why free is better.

Main Menu

Linked images

Started by MarquiseCarabas, March 01, 2013, 11:49:41 AM

Previous topic - Next topic

MarquiseCarabas

When setting up my new SMF forum, I noticed that the img and url tags can't be combined. When I post something like...
[url=URL_HERE][img]IMAGE_HERE[/img][/url]
... only the URL tag is interpreted, resulting in a link with the text '[img ]IMAGE_HERE[/img ]' instead of the image.

I assumed this was a standard issue of SMF and there would be a mod for it, but the only mod I found was one that adds a BBcode button to insert both tags at once - suggesting that the functionality should be there in the first place. A quick test on this forum revealed that it works here. Does anyone have any idea why it doesn't on my forum? It's version 2.0.4.

Shambles

Do the two BBCodes work ok in isolation?

MarquiseCarabas

Yes, they work perfectly, just not together.

MrPhil

[url=http://www.google.com][img]http://www.google.com/images/srpr/logo4w.png[/img][/url]



Seems to work OK here. Are you using the tags correctly? Do you have any mods installed?

Shambles

Quote
Do you have any mods installed?

As well as answering that, do you have access to your file system to be able to copy a file to one of your posts here? I'm thinking of Sources/Subs.php, in particular the section(s) that declare the url tag

$codes = array (
....
array(
'tag' => 'url',

MarquiseCarabas

Copied your code to my forum, doesn't work. I'm using the codes the exact same way and one of mine (that didn't work on my forum) worked perfectly when I previewed it here.

Thought I checked my mods already, but it turns out this one is causing the trouble: http://custom.simplemachines.org/mods/index.php?mod=1293

If I uninstall it, linked images work fine. I'd like to keep it though...

The url part of Subs.php (it's modified by the local url title mod):

array(
'tag' => 'url',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link" target="_blank">$2</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
),


And because it might be useful, the install file of the local urls mod:
<?xml version="1.0"?>
<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification">
<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/">
<id>LHVWB:ShowLocalUrlTitles</id>
<version>2.0.1</version>
<file name="$sourcedir/Subs.php">
<operation>
<search position="replace"><![CDATA[
// Never show smileys for wireless clients.  More bytes, can't see it anyway :P.
]]></search>
<add><![CDATA[
// Load up the show local url title functions. The complicated loading method is there to stop errors on uninstallation.
global $sourcedir;
static $loaded_local_url_parser = false;
if (!$loaded_local_url_parser && (empty($_GET['action']) || empty($_GET['area']) || $_GET['action'] != 'admin' || $_GET['area'] != 'packages'))
{
$loaded_local_url_parser = true;
require_once($sourcedir . '/Subs-ShowLocalUrlTitles.php');
}

// Never show smileys for wireless clients.  More bytes, can't see it anyway :P.
]]></add>
</operation>
<operation>
<search position="replace"><![CDATA[
array(
'tag' => 'url',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link" target="_blank">$1</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
),
array(
'tag' => 'url',
'type' => 'unparsed_equals',
'before' => '<a href="$1" class="bbc_link" target="_blank">',
'after' => '</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
'disallow_children' => array('email', 'ftp', 'url', 'iurl'),
'disabled_after' => ' ($1)',
),
]]></search>
<add><![CDATA[
array(
'tag' => 'url',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link" target="_blank">$2</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
),
array(
'tag' => 'url',
'type' => 'unparsed_equals_content',
'content' => '<a href="$2" class="bbc_link" target="_blank">$1</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
'disallow_children' => array('email', 'ftp', 'url', 'iurl'),
'disabled_after' => ' ($2)',
),
]]></add>
</operation>
<operation>
<search position="replace"><![CDATA[
array(
'tag' => 'iurl',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link">$1</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
),
array(
'tag' => 'iurl',
'type' => 'unparsed_equals',
'before' => '<a href="$1" class="bbc_link">',
'after' => '</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
if (substr($data, 0, 1) == \'#\')
$data = \'#post_\' . substr($data, 1);
elseif (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
'disallow_children' => array('email', 'ftp', 'url', 'iurl'),
'disabled_after' => ' ($1)',
),
]]></search>
<add><![CDATA[
array(
'tag' => 'iurl',
'type' => 'unparsed_content',
'content' => '<a href="$2" class="bbc_link">$1</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
),
array(
'tag' => 'iurl',
'type' => 'unparsed_equals_content',
'content' => '<a href="$2" class="bbc_link">$1</a>',
'validate' => create_function('&$tag, &$data, $disabled', '
if (substr($data, 0, 1) == \'#\')
$data = \'#post_\' . substr($data, 1);
elseif (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;
'),
'disallow_children' => array('email', 'ftp', 'url', 'iurl'),
'disabled_after' => ' ($2)',
),
]]></add>
</operation>
<operation>
<search position="replace"><![CDATA[
// No type means 'parsed_content'.
if (!isset($tag['type']))
{
// !!! Check for end tag first, so people can say "I like that [i] tag"?
$open_tags[] = $tag;
$message = substr($message, 0, $pos) . "\n" . $tag['before'] . "\n" . substr($message, $pos1);
$pos += strlen($tag['before']) - 1 + 2;
}
]]></search>
<add><![CDATA[
// No type means 'parsed_content'.
if (!isset($tag['type']))
{
// !!! Check for end tag first, so people can say "I like that [i] tag"?
$open_tags[] = $tag;
$message = substr($message, 0, $pos) . "\n" . $tag['before'] . "\n" . substr($message, $pos1);
$pos += strlen($tag['before']) - 1 + 2;
}
// Handle urls/iurls for the Show Local Url Titles mod.
elseif(($tag['tag'] == 'url') || ($tag['tag'] == 'iurl'))
{
// First tag type for urls just has the one url.
if ($tag['type'] == 'unparsed_content')
{
$pos2 = stripos($message, '[/' . substr($message, $pos + 1, strlen($tag['tag'])) . ']', $pos1);
if ($pos2 === false)
continue;

$data = substr($message, $pos1, $pos2 - $pos1);

if (isset($tag['validate']))
$tag['validate']($tag, $data, $disabled);

// Run the url through the get_ShowUrlTitle() function?
if (!empty($modSettings['ShowLocalUrlTitles_parsebbc']))
$text = get_local_url_title($data);
else
$text = $data;

$code = strtr($tag['content'], array('$2' => $text, '$1' => $data));
$message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos2 + 3 + strlen($tag['tag']));

$pos += strlen($code) - 1 + 2;
$last_pos = $pos + 1;
}
// Second tag type for urls can have a url value and a separate title.
elseif ($tag['type'] == 'unparsed_equals_content')
{
$quoted = false;
$pos2 = strpos($message, $quoted == false ? ']' : '&quot;]', $pos1);
if ($pos2 === false)
continue;
$pos3 = stripos($message, '[/' . substr($message, $pos + 1, strlen($tag['tag'])) . ']', $pos2);
if ($pos3 === false)
continue;

$data = array(
substr($message, $pos2 + ($quoted == false ? 1 : 7), $pos3 - ($pos2 + ($quoted == false ? 1 : 7))),
substr($message, $pos1, $pos2 - $pos1)
);

// Validation for my parking, please!
if (isset($tag['validate']))
$tag['validate']($tag, $data[1], $disabled);

// Run the url through the get_ShowUrlTitle() function, if we need to.
if (!empty($modSettings['ShowLocalUrlTitles_parsebbc']) && in_array($data[1], array(strtr($data[0], array('<br />' => '')), 'http://' . strtr($data[0], array('<br />' => '')))))
$data[0] = get_local_url_title($data[1]);

$code = strtr($tag['content'], array('$1' => $data[0], '$2' => $data[1]));
$message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos3 + 3 + strlen($tag['tag']));
$pos += strlen($code) - 1 + 2;
}
}
]]></add>
</operation>
<operation>
<search position="end" />
<add><![CDATA[
// Autolinks any urls in the text given. Extremely useful, but annoying to code all the same.
// Assumes that the text contains no "code" bbc.
function autolink_urls($text)
{
global $context;

// Don't attempt to autolink anything within these tags.
$no_autolink_tags = array(
'url',
'iurl',
'ftp',
'email',
);

$final_pos = strlen($text);
$parsed_text = '';
$pos = -1;
$last_pos = 0;
// Parse text, while there is still text to parse.
while ($pos < $final_pos && $last_pos < $final_pos)
{
// Assume that we are going to parse the rest of the text.
$pos = $final_pos;

// Try to find an earlier position, that starts a block of text we cannot parse.
$tag = '';
foreach ($no_autolink_tags as $no_autolink_tag)
{
if (($temp_pos = strpos($text, '[' . $no_autolink_tag, $last_pos + 1)) !== false && $temp_pos < $pos)
{
$pos = $temp_pos;
$tag = $no_autolink_tag;
}
}

// Get us the relevant data to parse.
$data = substr($text, $last_pos, $pos - $last_pos);

// Parse any urls that we can.
if (strlen($data) > 4 && (!isset($disabled['url']) && (strpos($data, '://') !== false || strpos($data, 'www.') !== false) && strpos($data, '[url') === false))
{
// Get rid of quotes.
$data = strtr($data, array('&#039;' => '\'', '&nbsp;' => $context['utf8'] ? "\xC2\xA0" : "\xA0", '&quot;' => '>">', '"' => '<"<', '&lt;' => '<lt<'));

// Only do this if the preg survives.
if (is_string($result = preg_replace(array(
'~(?<=[\s>\.(;\'"]|^)((?:http|https)://[\w\-_%@:|]+(?:\.[\w\-_%]+)*(?::\d+)?(?:/[\w\-_\~%\.@,\?&;=#(){}+:\'\\\\]*)*[/\w\-_\~%@\?;=#}\\\\])~i',
'~(?<=[\s>(\'<]|^)(www(?:\.[\w\-_]+)+(?::\d+)?(?:/[\w\-_\~%\.@,\?&;=#(){}+:\'\\\\]*)*[/\w\-_\~%@\?;=#}\\\\])~i'
), array(
'[url]$1[/url]',
'[url=http://$1]http://$1[/url]'
), $data)))
$data = $result;

// Put back the quotes.
$data = strtr($data, array('\'' => '&#039;', $context['utf8'] ? "\xC2\xA0" : "\xA0" => '&nbsp;', '>">' => '&quot;', '<"<' => '"', '<lt<' => '&lt;'));
}

// Find where we can start parsing again.
if (!empty($tag) && ($last_pos = strpos($text, '[/' . $tag . ']', $pos)) !== false)
$last_pos += strlen('[/' . $tag . ']');
// Otherwise we've reached the end of the line...
else
$last_pos = $final_pos;

// Give back any parsed and unparsed content.
$parsed_text .= $data . substr($text, $pos, $last_pos - $pos);
}

return $parsed_text;
}
]]></add>
</operation>
</file>
<file name="$sourcedir/Subs-Post.php">
<operation>
<search position="replace"><![CDATA[
global $user_info, $modSettings, $smcFunc, $context;
]]></search>
<add><![CDATA[
global $user_info, $modSettings, $smcFunc, $context, $sourcedir;

// Load up the show local url title functions.
require_once($sourcedir . '/Subs-ShowLocalUrlTitles.php');
]]></add>
</operation>
<operation>
<search position="replace"><![CDATA[
fixTags($parts[$i]);
]]></search>
<add><![CDATA[
fixTags($parts[$i]);

// Autolink urls?
if (!empty($modSettings['ShowLocalUrlTitles_autolink']))
$parts[$i] = autolink_urls($parts[$i]);

// Fix any local urls.
if (!empty($modSettings['ShowLocalUrlTitles_posting']))
{
$parts[$i] = preg_replace_callback('~\[url(=.*?)?\](.*?)\[/url\]~', 'get_local_url_title__callback', $parts[$i]);
$parts[$i] = preg_replace_callback('~\[iurl(=.*?)?\](.*?)\[/iurl\]~', 'get_local_iurl_title__callback', $parts[$i]);
}
]]></add>
</operation>
</file>
<file name="$sourcedir/ManageSettings.php">
<operation>
<search position="replace"><![CDATA[
// Mod authors, once again, if you have a whole section to add do it AFTER this line, and keep a comma at the end.
]]></search>
<add><![CDATA[
// Mod authors, once again, if you have a whole section to add do it AFTER this line, and keep a comma at the end.
'parsetitles' => 'ParseLocalURLTitles',
]]></add>
</operation>
<operation>
<search position="replace"><![CDATA[
// Mod authors, add any settings UNDER this line. Include a comma at the end of the line and don't remove this statement!!
]]></search>
<add><![CDATA[
// Mod authors, add any settings UNDER this line. Include a comma at the end of the line and don't remove this statement!!
array('title', 'ShowLocalUrlTitles_heading'),
array('check', 'ShowLocalUrlTitles_parsebbc'),
array('check', 'ShowLocalUrlTitles_posting'),
array('check', 'ShowLocalUrlTitles_autolink'),
array('message', 'ShowLocalUrlTitles_parse_existing', 'text_label' => '<a href="' . $scripturl . '?action=admin;area=modsettings;sa=parsetitles;' . $context['session_var'] . '=' . $context['session_id'] . '" onClick="return confirm(\'' . $txt['ShowLocalUrlTitles_parse_existing_confirmation'] . '\');">' . $txt['ShowLocalUrlTitles_parse_existing'] . '</a>'),
'',
]]></add>
</operation>
<operation>
<search position="end" />
<add><![CDATA[
// This function performs the conversion of any local urls in existing posts.
function ParseLocalURLTitles()
{
global $modSettings, $smcFunc, $context, $sourcedir, $cache_titles;

// Are you meant to be here?
isAllowedTo('admin_forum');

// Check their session.
checkSession('request');

// Load the required parsing functions.
require_once($sourcedir . '/Subs-Post.php');

// These variables force the parsing functions to parse the urls as required.
$modSettings['ShowLocalUrlTitles_posting'] = true;
$modSettings['ShowLocalUrlTitles_autolink'] = true;

// Load the cache.
$modSettings['ShowLocalUrlTitles_caching'] = true;
$cache_titles = cache_get_data('show_local_url_titles');
$cache_titles = !empty($cache_titles) ? $cache_titles : array();

// Some starting values.
$context['msg'] = empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'];
$context['start_time'] = time();
$context['first_step'] = !isset($_REQUEST[$context['session_var']]);
$context['last_step'] = false;

// Use the generic "not done" template.
$context['sub_template'] = 'not_done';
$context['continue_post_data'] = '';
$context['continue_countdown'] = 3;

// Get the maximum message id.
$request = $smcFunc['db_query']('', '
SELECT MAX(id_msg)
FROM {db_prefix}messages',
array(
)
);
list($max_msg) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);

// Parse one message at a time.
while ($context['msg'] < $max_msg)
{
// Get the next message.
$request = $smcFunc['db_query']('', '
SELECT body, id_msg
FROM {db_prefix}messages
WHERE id_msg >= {int:next_msg}
ORDER BY id_msg
LIMIT 1',
array(
'next_msg' => $context['msg'] + 1,
)
);
list($body, $context['msg']) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);

// Parse the body.
// Note: This could be improved, by avoiding use of the preparsing functions.
$body = un_preparsecode($body);
preparsecode($body);

// Save the message.
$smcFunc['db_query']('', '
UPDATE {db_prefix}messages
SET body = {string:body}
WHERE id_msg = {int:id_msg}
LIMIT 1',
array(
'body' => $body,
'id_msg' => $context['msg'],
)
);

// After ten seconds interrupt.
if (time() - $context['start_time'] > 10)
{
// Update the cache.
cache_put_data('show_local_url_titles', $cache_titles);

// Calculate an approximation of the percentage done.
$context['continue_percent'] = round(100 * $context['msg'] / $modSettings['totalMessages'], 1);
$context['continue_get_data'] = '?action=admin;area=modsettings;sa=parsetitles;msg=' . $context['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'];
return;
}
}

// If we're here, we must be done.
$context['continue_percent'] = 100;
$context['continue_get_data'] = '?action=admin;area=modsettings';
$context['last_step'] = true;
$context['continue_countdown'] = -1;

// Kill the cache, otherwise it will be storing a lot of data!
cache_put_data('show_local_url_titles', null);
}
]]></add>
</operation>
</file>
</modification>

Kindred

since you have identifed the mod as being the problem, you should take any further questions to the support topic for that mod... :)
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

Shambles

Yep, and that problem is discussed extensively within the support topic for the mod :)

MarquiseCarabas

Should have looked there first. A lot of people had the same problem and someone fixed it. Thanks for the help anyway!

Advertisement: