Customising function constructPageIndex (nasty evil stuffz)

Started by Antechinus, July 03, 2014, 09:56:07 PM

Previous topic - Next topic

Arantor

That last part is what I was getting at with the buffer hook business.

Hmm, I do wonder if I should consider adding some of the ideas from here into my  gallery mod because that replaces constructPageIndex with its own version.
Holder of controversial views, all of which my own.


Antechinus

Do you want the final code for what I'm running? IMO having a page index without next/previous buttons is just bonkers.

Arantor

Well, mine is vastly different in terms of logic, since I do things no one else does.

For example, if on page 2, I don't have a different link back to page 1, I have the canonical link, e.g. domain.com/index.php?media/item/my-item.1/ vs domain.com/index.php?media/item/my-item.1/page-2/ which also doesn't play nice with cPI hence I rolled my own. Am curious about markup since I emulated the visual style of SMF's standard, even down to the click to expand which also needed reworking.

But I am interested in thoughts on first/prev/next/last vs prev/next buttons.
Holder of controversial views, all of which my own.


Antechinus

#43
Ok well my markup is this, chosen so any element can easily be styled. This works flawlessly on any default template, with the next/previous only showing up on pages where they should (ie: not inside topics on message index).

My 2c about first/last buttons is that they are a waste of space. If doing things with mobile in mind you want compact. First/last buttons are just extra bloat, since SMF always displays the links to the first and last pages anyway FFS, and if you leave those two extra buttons out, and set the admin setting to 1 contiguous page, the whole page index while fit nicely on one line even with next/previous buttons.

This is good, since phones are relevant these days. Having more than one contiguous page displayed is pointless, since it's basically an hangover from the stupid old days when SMF did not have the things it really needs: previous page and next page buttons. So, if you're fixing that problem anyway, no worries.

Anyway, markup.

function constructPageIndex($base_url, &$start, $max_value, $num_per_page, $flexible_start = false)
{
global $modSettings, $txt;

// 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) == 0 ? $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%3$s" href="' . ($flexible_start ? $base_url : strtr($base_url, array('%' => '%%')) . ';start=%1$d') . '">%2$s</a>';

// Compact pages is off or on?
if (empty($modSettings['compactTopicPagesEnable']))
{
// Show the left arrow.
$pageindex = $start == 0 ? ' ' : sprintf($base_link, $start - $num_per_page, '&nbsp;', ' previous_page');

// Show all the pages.
$display_page = 1;
for ($counter = 0; $counter < $max_value; $counter += $num_per_page)
$pageindex .= $start == $counter && !$start_invalid ? '<a class="navPages current_page">' . $display_page++ . '</a>' : sprintf($base_link, $counter, $display_page++, '');

// Show the right arrow.
$display_page = ($start + $num_per_page) > $max_value ? $max_value : ($start + $num_per_page);
if ($start != $counter - $max_value && !$start_invalid)
$pageindex .= $display_page > $counter - $num_per_page ? ' ' : sprintf($base_link, $display_page, '&nbsp;', ' next_page');
}
else
{
// If they didn't enter an odd value, pretend they did.
$PageContiguous = (int) ($modSettings['compactTopicPagesContiguous'] - ($modSettings['compactTopicPagesContiguous'] % 2)) / 2;
$pageindex = '';

if (!$start_invalid)
{
// Show 'Prev'
if ($start > ($num_per_page - 1))
$pageindex = sprintf($base_link, $start - $num_per_page, '&nbsp;', ' previous_page');
}

// Show the first page. (>1< ... 6 7 [8] 9 10 ... 15)
if ($start > $num_per_page * $PageContiguous)
$pageindex .= sprintf($base_link, 0, '1', '');

// Show the ... after the first page.  (1 >...< 6 7 [8] 9 10 ... 15)
if ($start > $num_per_page * ($PageContiguous + 1))
$pageindex .= '<span class="navPages page_dots" style="cursor: pointer;" onclick="' . htmlspecialchars('expandPages(this, ' . JavaScriptEscape(($flexible_start ? $base_url : strtr($base_url, array('%' => '%%')) . ';start=%1$d')) . ', ' . $num_per_page . ', ' . ($start - $num_per_page * $PageContiguous) . ', ' . $num_per_page . ');') . '">...</span>';

// Show the pages before the current one. (1 ... >6 7< [8] 9 10 ... 15)
for ($nCont = $PageContiguous; $nCont >= 1; $nCont--)
if ($start >= $num_per_page * $nCont)
{
$tmpStart = $start - $num_per_page * $nCont;
$pageindex .= sprintf($base_link, $tmpStart, $tmpStart / $num_per_page + 1,'');
}

// Show the current page. (1 ... 6 7 >[8]< 9 10 ... 15)
if (!$start_invalid)
$pageindex .= '<span class="navPages current_page">' . ($start / $num_per_page + 1) . '</span>';
else
$pageindex .= sprintf($base_link, $start, $start / $num_per_page + 1, '');

// Show the pages after the current one... (1 ... 6 7 [8] >9 10< ... 15)
$tmpMaxPages = (int) (($max_value - 1) / $num_per_page) * $num_per_page;
for ($nCont = 1; $nCont <= $PageContiguous; $nCont++)
if ($start + $num_per_page * $nCont <= $tmpMaxPages)
{
$tmpStart = $start + $num_per_page * $nCont;
$pageindex .= sprintf($base_link, $tmpStart, $tmpStart / $num_per_page + 1,'');
}

// Show the '...' part near the end. (1 ... 6 7 [8] 9 10 >...< 15)
if ($start + $num_per_page * ($PageContiguous + 1) < $tmpMaxPages)
$pageindex .= '<span class="navPages page_dots" style="cursor: pointer;" onclick="expandPages(this, \'' . ($flexible_start ? strtr($base_url, array('\'' => '\\\'')) : strtr($base_url, array('%' => '%%', '\'' => '\\\'')) . ';start=%1$d') . '\', ' . ($start + $num_per_page * ($PageContiguous + 1)) . ', ' . $tmpMaxPages . ', ' . $num_per_page . ');">...</span>';

// Show the last number in the list. (1 ... 6 7 [8] 9 10 ... >15<)
if ($start + $num_per_page * $PageContiguous < $tmpMaxPages)
$pageindex .= sprintf($base_link, $tmpMaxPages, $tmpMaxPages / $num_per_page + 1, '');

if (!$start_invalid)
{
// Show 'Next'.
$display_page = ($start + $num_per_page) > $max_value ? $max_value : ($start + $num_per_page);
if (($display_page <= $tmpMaxPages)&&($tmpMaxPages > 1))
$pageindex .= sprintf($base_link, $display_page, '&nbsp;', ' next_page');
}
}

return $pageindex;
}


Like I mentioned earlier, just having the non-breaking space generated in markup is handy when it comes to styling up the pseudo elements which do the visible indicators in the CSS, because it allows you to get things aligned nicely by just using vertical-align: middle; on the pseudos. They need a bit of "text" in the parent anchor for this to work.

Antechinus

Oh by the way Ranty one: that old dropdown mod that you'd almost forgotten about seems, on further reflection, to be probably the ideal way of handling page index presentation on phones, if it is used in combination with next/previous page buttons (just for greater convenience). Selects can be made to look quite decent these days, even on dark themes on iOS and even without js hacks to mutate the default styling.

Obviously it would still be possible to have an expanded page index presentation on desktop, if anyone actually wanted it, but a select makes a lot of sense on phones. So I'd be marking it up to put the select right in the middle, and the next/previous buttons at each end. I might look into this.

Arantor

Holder of controversial views, all of which my own.


Antechinus

Yeah I was just mentioning it to Chalky on her site. She liked the idea for phones too, and she uses them a lot so would know. Seems like a winner.

Arantor

Yup. It'd be a pain for me to implement because I do weird stuff in my copy of the function but that's what I get for showing off with pretty URLs :P
Holder of controversial views, all of which my own.


Advertisement: