Action: Navigation

Status: Implemented, work in progress
version: 0.3 (see repo)



Scroll to the previous or next page
Navigate between predefined pages / chapters


For display at the top and bottom of the page.


Static or dynamic, formatter or action.

  • The very moment it loads metadata like the page title via the page tag its dynamic.

{{navigation
  prev="ChapterOne"
  next="ChapterTwo"
  main="Overview"
}}	

1. Determination of pages and context

  • cluster
    • how to define the order
    • subset of pages
  • predefined array, pages="Page1, Page2, Page3, ..."
  • via parameter prev="PreviousPage", next="NextPage" and main="MainPage"

It is possible to define the navigation on every single page or include a dedicated section as page with dynamic determination.

2. Options

  • noinclude
    • <!--noinclude-->, <!--/noinclude-->
  • layout
    • table=1|0
  • style
  • link text
    • page title - title=1
    • default
    • custom

CSS

  • no-print

3. Action

3.1. via link()

source:master/src/action/navigation.php

<?php

if (!defined('IN_WACKO'))
{
    exit;
}

/* navigation action:
 *
 *
TODO:
    - add option to choose custom menu as data source
*/

$info = <<<EOD
Description:
    Generates navigation bars to navigate between chapters of a book.

Usage:
    {{navigation}}

Options:
    [main="Overview"]
        tag of overview
    [prev="PreviousPage"]
        tag of previous chapter
    [next="NextPage"]
        tag of next chapter
    [title=0|1]
        uses page title for links
EOD;

// set defaults
$help        ??= 0;
$main        ??= '';
$next        ??= '';
$prev        ??= '';
$table        ??= 1;
$title        ??= 0;
$track        ??= true; // seems to have no effect


if ($help)
{
    $tpl->help    = $this->help($info, 'navigation');
    return;
}

// resolve relative tag
$_main    = $this->unwrap_link($main);
$_next    = $this->unwrap_link($next);
$_prev    = $this->unwrap_link($prev);

// preload link data
$pages    = [$_prev, $_main, $_next];

foreach ($pages as $page)
{
    if ($page != '')
    {
        $q_spages[]        = $this->db->q($page);
    }
}

$pages = $this->db->load_all(
    'SELECT ' . $this->page_meta . ' ' .
    'FROM ' . $this->prefix . 'page ' .
    'WHERE tag IN ( ' . implode(', ', $q_spages) . ' ) '
    , true);

$__main    = null;
$__next    = null;
$__prev    = null;

foreach ($pages as $page)
{
    $this->cache_page($page, true);
    $page_ids[]    = $page['page_id'];
    $this->page_id_cache[$page['tag']] = $page['page_id'];

    if ($page['tag'] == $_prev)
    {
        $__prev = $page;
    }
    if ($page['tag'] == $_main)
    {
        $__main = $page;
    }
    if ($page['tag'] == $_next)
    {
        $__next = $page;
    }
}

// cache acls
$this->preload_acl($page_ids, ['read']);

// fall back to tag
if (!$__prev)
{
    $__prev['tag']        = $_prev;
    $__prev['title']    = '';
}
if (!$__main)
{
    $__main['tag']        = $_main;
    $__main['title']    = '';
}
if (!$__next)
{
    $__next['tag']        = $_next;
    $__next['title']    = '';
}

// link text
$__main['text'] = '↑ ' .    ($title ? $__main['title'] : $this->_t('Overview'));
$__prev['text'] = '« ' .    ($title ? $__prev['title'] : $this->_t('Back'));
$__next['text'] =            ($title ? $__next['title'] : $this->_t('Next'))        . ' »';

$__main['title'] = ($title ? '' : $__main['title']);
$__prev['title'] = ($title ? '' : $__prev['title']);
$__next['title'] = ($title ? '' : $__next['title']);

// define navigation links
$tpl->enter($table ? 'tbl_' : 'div_');
$tpl->main_link            = $this->link('/' . $__main['tag'], '', $__main['text'], $__main['title'], $track, true, false);

if ($prev)
{
    $tpl->prev_link        = $this->link('/' . $__prev['tag'], '', $__prev['text'], $__prev['title'], $track, true, false);
}

if ($next)
{
    $tpl->next_link        = $this->link('/' . $__next['tag'], '', $__next['text'], $__next['title'], $track, true, false);
}

if ($prev & $next)
{
    $tpl->separator    = true;
}

$tpl->leave();

3.2. via href()

static, no metadata lookup


<?php

if (!defined('IN_WACKO'))
{
    exit;
}

/* navigation action:
 *
 *
TODO:
    - add option to choose custom menu as data source
*/

$info = <<<EOD
Description:
    Generates navigation bars to navigate between chapters of a book.

Usage:
    {{navigation}}

Options:
    [main="Overview"]
        tag of overview
    [prev="PreviousPage"]
        tag of previous chapter
    [next="NextPage"]
        tag of next chapter
EOD;

// set defaults
$help            ??= 0;
$main            ??= '';
$next            ??= '';
$prev            ??= '';

if ($help)
{
    $tpl->help    = $this->help($info, 'navigation');
    return;
}


$tpl->enter('table_');
$tpl->main_href        = $this->href('', $this->unwrap_link($main));
$tpl->prev_href        = $this->href('', $this->unwrap_link($prev));
$tpl->next_href        = $this->href('', $this->unwrap_link($next));
$tpl->leave();

4. Template

The main goal is to have a customizable standard template for scrolling between pages.


« Previous Content
Next »
← Back to overview « Back | Next »

The content section even could hold a drop down or fly-out menu with all available pages / chapters.
The next and previous button should show the page title via title="Chapter Two" of the page.
The link text can be set individually.

  • prev, previous, Previous Chapter, back
  • next, Next Chapter, forward
  • Overview, Index, Content
  • page title, page_tag
  • custom link text
  • «, », ↑, ←, →

source:master/src/action/template/navigation.tpl

[ === main === ]
<!--noinclude-->
	[ ' help ' ] 
	<nav class="nav-chapter no-print">
	[= tbl _ =
		<table>
			<tr>
				<td>
				[= prev _ =
					[ ' link ' ]
				=]
				</td>
				<td>
				[= main _ =
					[ ' link ' ]
				=]
				</td>
				<td>
				[= next _ =
					[ ' link ' ]
				=]
				</td>
			</tr>
		</table>
	=]
	[= div _ =
		[= main _ =
			[ ' link ' ]
		=]
		<div class="pagination">
		[= prev _ =
			[ ' link ' ]
		=]
		[= separator _ =
			[ ' nonstatic ' ]
		 | 
		=]
		[= next _ =
			[ ' link ' ]
		=]
		</div>
	=]
	</nav>
<!--/noinclude-->	

[ === main === ]
<!--noinclude-->
	[ ' help ' ] 
	<nav class="nav-capter no-print">
	[= table _ =
		<table>
			<tr>
				<td>
				[= prev _ =
					<a href="[ ' href ' ]">« [ ' _t: Back ' ]</a>
				=]
				</td>
				<td>
				[= main _ =
					<a href="[ ' href ' ]">↑ [ ' _t: Overview ' ]</a>
				=]
				</td>
				<td>
				[= next _ =
					<a href="[ ' href ' ]">[ ' _t: Next ' ] »</a>
				=]
				</td>
			</tr>
		</table>
	=]
	[= div _ =
		<div class="nav-capter">

		</div>
	=]
	</nav>
<!--/noinclude-->	

4.1. CSS

add to default.css

/* navigation action ------------- */
.nav-chapter {
	background-color: rgb(241, 241, 241);
	padding: 10px 10px;
}
.nav-chapter td:nth-child(1) {
	text-align:left;
	white-space: nowrap;
}
.nav-chapter td:nth-child(2) {
	text-align: center;
width: 100%;
}
.nav-chapter td:nth-child(3) {
	text-align:right;
	white-space: nowrap;
} 	

5. ToDo

workout of details

  • track links (?)
  • add option for alternate layout: table=1|0 (table|div layout)
  • add option for alternate link text
    • alternate standard text or combination
    • via parameter, e.g.
      • prev_text="Custom link text"
      • via delimiter after the tag prev="ChapterOne|First Chapter"
      • title=1 - uses page title
    • via sub template
  • add option to choose custom menu as data source
  • simplify and refactor draft
  • naming and wording
  • print handler displays links for hidden action

Add a good enough version (that will do for most cases) to the core, add some examples here for more advanced templates for copy and paste.

6. Example

/Book/ChapterOne

{{navigation main="/Book" next="ChapterTwo"}}	

/Book/ChapterTwo

{{navigation main="/Book" prev="ChapterOne" next="ChapterThree"}}	

/Book/ChapterThree

{{navigation 
  main="/Book" 
  prev="ChapterTwo" 
  next="ChapterFour"
  title=1
}}	

7. Changelog

0.1 Intitial version
0.2 adds nav-chapter class to CSS and message set for 'Overview'
0.3 adds parameter title=0|1, shows page title as link text

8. See also