sprintf syntax for language string in Subs.php?

Started by Antechinus, August 31, 2015, 06:33:53 PM

Previous topic - Next topic

Antechinus

Ok, this has me stumped. I should stick to CSS.

So I'm making a mod for the page index. The plan is that the select which holds the list of all pages will just list them as Page1, Page 2 etc all the way down, but the page you are on will be shown in the top of the select (ie: the box you see when it's not all expanded) as "Page 5 of 27" or whatever.

This is so there's an indication of where you are up to in the thread, since with the old page index being deprecated the select should (I think) give you an indication of the total number of pages.

So I can do that, except for i18n. I had the bright idea that I should do the language strings with sprintf, so that if some language other than English requires a completely different order of words and numbers it will be possible to deal with this in the languages files.

The result was a massively borked test site. :D

The question is: how to do it without borking my test site, or any other sites for that matter?

The code I have working in Subs.php is this:

<?php
// Constructs a page list.
// $pageindex = constructPageIndex($scripturl . '?board=' . $board, $_REQUEST['start'], $num_messages, $maxindex, true);
function constructPageIndex($base_url, &$start$max_value$num_per_page$flexible_start false$txt)
{
global $modSettings;

// Save whether $start was less than 0 or not.
$start = (int) $start;
$start_invalid $start 0;

// Make sure $start is a proper variable - not less than 0.
if ($start_invalid)
$start 0;
// Not greater than the upper bound.
elseif ($start >= $max_value)
$start max(0, (int) $max_value - (((int) $max_value % (int) $num_per_page) == $num_per_page : ((int) $max_value % (int) $num_per_page)));
// And it has to be a multiple of $num_per_page!
else
$start max(0, (int) $start - ((int) $start % (int) $num_per_page));

// Wireless will need the protocol on the URL somewhere.
if (WIRELESS)
$base_url .= ';' WIRELESS_PROTOCOL;

$base_link '<a class="navPages %2$s" href="' . ($flexible_start $base_url strtr($base_url, array('%' => '%%')) . ';start=%1$d') . '">%3$s</a> ';

if($max_value $num_per_page)
{
$dropdown_url = ($flexible_start $base_url strtr($base_url, array('%' => '%%')) . ';start=');
if(strpos($dropdown_url'%1$d') === false)
{
if(strpos($dropdown_url'start=') === false)
{
$dropdown_url .= ';start=%1$d';
}
else
{
$dropdown_url str_replace('start=''start=%1$d'$dropdown_url);
}
}

$base_dropdown '<select class="navPages_select" onchange="javascript:window.location=(\'' $dropdown_url '\').replace(/%1\$d/, this.value);">';
$display_page 0;
$myPage = ($start $num_per_page);
$tmpMaxPages = (int) (($max_value 1) / $num_per_page) * $num_per_page;
for ($counter 0$counter $max_value$counter += $num_per_page)
{
$base_dropdown .= '<option value="' . ($num_per_page $display_page) . '"';
if($display_page == $myPage$base_dropdown .= ' selected="selected"';
$base_dropdown .= '>';

$base_dropdown .= 'Page ' . ++$display_page;
if($display_page == $myPage 1$base_dropdown .= ' of '.($tmpMaxPages $num_per_page 1);
$base_dropdown .= '</option>';
}

$base_dropdown .= '</select>';
// Show 'Prev'
if ($start >= $num_per_page)
$base_dropdown .= sprintf($base_link$start $num_per_page'floatleft''&laquo;');
// Show 'Next'.
$display_page = ($start $num_per_page) > $max_value $max_value : ($start $num_per_page);
if (($display_page <= $tmpMaxPages)&&($tmpMaxPages 1))
$base_dropdown .= sprintf($base_link$display_page'floatright''&raquo;');
}
else
{
$base_dropdown "";
}

return $base_dropdown;
}
?>


That all works just fine, although I'm going to ditch laquo and raquo since they would be arse about in RTL languages (I'll fix those to use pseudos, with content editable in the CSS).

The problem comes when I want to use this in Subs.php:

<?php
// Constructs a page list.
// $pageindex = constructPageIndex($scripturl . '?board=' . $board, $_REQUEST['start'], $num_messages, $maxindex, true);
function constructPageIndex($base_url, &$start$max_value$num_per_page$flexible_start false$txt)
{
global $modSettings;

// Save whether $start was less than 0 or not.
$start = (int) $start;
$start_invalid $start 0;

// Make sure $start is a proper variable - not less than 0.
if ($start_invalid)
$start 0;
// Not greater than the upper bound.
elseif ($start >= $max_value)
$start max(0, (int) $max_value - (((int) $max_value % (int) $num_per_page) == $num_per_page : ((int) $max_value % (int) $num_per_page)));
// And it has to be a multiple of $num_per_page!
else
$start max(0, (int) $start - ((int) $start % (int) $num_per_page));

// Wireless will need the protocol on the URL somewhere.
if (WIRELESS)
$base_url .= ';' WIRELESS_PROTOCOL;

$base_link '<a class="navPages %2$s" href="' . ($flexible_start $base_url strtr($base_url, array('%' => '%%')) . ';start=%1$d') . '">%3$s</a> ';

if($max_value $num_per_page)
{
$dropdown_url = ($flexible_start $base_url strtr($base_url, array('%' => '%%')) . ';start=');
if(strpos($dropdown_url'%1$d') === false)
{
if(strpos($dropdown_url'start=') === false)
{
$dropdown_url .= ';start=%1$d';
}
else
{
$dropdown_url str_replace('start=''start=%1$d'$dropdown_url);
}
}

$base_dropdown '<select class="navPages_select" onchange="javascript:window.location=(\'' $dropdown_url '\').replace(/%1\$d/, this.value);">';
$display_page 0;
$myPage = ($start $num_per_page);
$tmpMaxPages = (int) (($max_value 1) / $num_per_page) * $num_per_page;
for ($counter 0$counter $max_value$counter += $num_per_page)
{
$base_dropdown .= '<option value="' . ($num_per_page $display_page) . '"';
if($display_page == $myPage$base_dropdown .= ' selected="selected"';
$base_dropdown .= '>';

if($display_page == $myPage 1){
$base_dropdown .= sprintf($txt['navPages_selected'], ++$display_page, ($tmpMaxPages $num_per_page 1));
}
else{
$base_dropdown .= sprintf($txt['navPages_select'], ++$display_page);
}

$base_dropdown .= '</option>';
}

$base_dropdown .= '</select>';
// Show 'Prev'
if ($start >= $num_per_page)
$base_dropdown .= sprintf($base_link$start $num_per_page'floatleft''&laquo;');
// Show 'Next'.
$display_page = ($start $num_per_page) > $max_value $max_value : ($start $num_per_page);
if (($display_page <= $tmpMaxPages)&&($tmpMaxPages 1))
$base_dropdown .= sprintf($base_link$display_page'floatright''&raquo;');
}
else
{
$base_dropdown "";
}

return $base_dropdown;
}
?>


With this in the languages files:

<?php
//In languages files, strings would look like this:
$txt['navPages_select'] ='Page %1$s';
$txt['navPages_selected'] ='Page %1$s of %2$s';
?>


That combination massively borks the whole site, which is entertaining but not the desired result. What am I missing here?

Antechinus

Ok NVM. I fixed this one too. Problems were:

1/ Some nong hadn't noticed he'd declared $txt as a variable up here - function constructPageIndex($base_url, &$start, $max_value, $num_per_page, $flexible_start = false, $txt) - instead of two lines down where the globals are declared. I knew it was supposed to be declared as a global. Must have had a brain fart. ::)

2/ Other problem was that, after RTFPHPM a bit, I figured out I should write the language strings with %1$d instead of %1$s, coz that's how you write the buggers when you're calling up a number instead of a string (which I didn't know before).

So it all works now. :D

(I had sometimes wondered why those sprintf thingies used %1$s in some places and %1$d in others...)

* Antechinus is PHP expert now. :P

Advertisement: