Skip to content

Numerator full documentation

Aviel Fedida edited this page Apr 26, 2015 · 6 revisions

2 Approaches

This framework has 2 approaches, after you set the framework as you'r about to see, you can use 2 methods:

  1. getArray will return the result as array that you can iterate on your own.
  2. getHtml will return the result as plain html(the html contain classes, its on your responsibility to style those classes) that you can echo/print to your page.

The getArray method will return:

[4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8]

The getHtml will return:

<div class="n-container">
    <a class="n-page" href="?page=4">4</a>
    <a class="n-page" href="?page=5">5</a>
    <span class="n-current-page">6</span>
    <a class="n-page" href="?page=7">7</a>
    <a class="n-page" href="?page=8">8</a>
</div>

Both methods explained widely later on

Jump into code

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('&');
$Numerator->setNumerator([2, 2, 5, 95]);
echo $Numerator->getHtml(8);

Those 4 simple steps are all you need to set up Numerator.php for the following result:

<div class="n-container">
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
</div>

Line by line

Include Numerator.php(I used require_once):

require_once 'Numerator.php';

Creating Numerator object:

$Numerator = new \Numerator\Numerator('&');

\Numerator\Numerator is used because this framework is using PHP namespaces(the reason for requiring PHP 5.3.0) with the name Numerator to avoid class name collision.

The \Numerator\ part is the namespace and the following Numerator is the name of the class.

The '&' argument represent pagination method, pagination methods will be explained later on.

Next we setting our Numerator class using setNumerator:

$Numerator->setNumerator([2, 2, 5, 95]);

For start I would like to focus the first 2 array elements [2, 2], they are the core functionality of this framework.

What is the core functionality?

The first element represent pages you want to appear at the left side of the current page:

<div class="n-container">
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
</div>

Notice the class n-current-page, there are 2 page links at the left side of it, as pointed out by the first array element.

The second element represent pages you want to appear at the right side of the current page:

<div class="n-container">
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
</div>

So [2, 2] should provide:

<div class="n-container">
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
</div>

If you provide [2, 0] Numerator will force the use of next navigator:

<div class="n-container">
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
    <a class="n-prev-next" href="?page=9">»</a>
</div>

You may notice that there are no pages links after the current page(n-current-page class), and Numerator forces the use of next navigator.

For [0, 2] Numerator will force the use of previous navigator:

<div class="n-container">
    <a class="n-prev-next" href="?page=9">«</a>
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
</div>

And finally for [0, 0] the result will be:

<div class="n-container">
    <a class="n-prev-next" href="?page=9">«</a>
    <span class="n-current-page">8</span>
    <a class="n-prev-next" href="?page=9">»</a>
</div>

As you remember the settings array was [2, 2, 5, 95], for now I want to keep focusing on the [2, 2], about [5, 95] don't worry they will be explained later on.

So to illustrate better how the left/right pages concept works I will use getArray method.

Lets replace the method getHtml with getArray:

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('&');
$Numerator->setNumerator([2, 2, 5, 95]);
/* I'm using var_dump() to view the returned array from
 * getArray method, as you can see none of the above
 * lines wasn't changed, only the method getHtml
 * was replaced with getArray.
 * */
var_dump($Numerator->getArray(8));

The returned array is:

[6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10]

Before you're asking why the keys and the values are the same, don't worry I will get to it.

Lets continue with our subject, I will assume you are using [2, 2], lets try different current pages, the reason is because Numerator will result differently depending on the left/right settings and the current page.

So if we have [2, 2] and the current page is

What if the current page is 2 the result we *don't want is:

[0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4]

So the problem is that there is no page 0, well Numerator will actually result in:

[1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]

Numerator "figure out" that there is extra slot that cannot be used by the left side so it assign this slot to the right side.

Why keys and values are the same?

This section is important for users that want to use getArray approach and iterate the returned array, if you don't want any special behavior you can use getHtml, I still suggest to learn this section for better understanding because eventually getHtml uses getArray internally.

Remember I said that & represent pagination method?, well its not the only method.

Lets see how would $ will present our pages:

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('$'); // Method is now $
$Numerator->setNumerator([2, 2, 5, 95]);

Using getArray result with:

[6 => '26-30', 7 => '31-35', 8 => '36-40', 9 => '41-45', 10 => '46-50']

Using getHtml result with:

<div class="n-container">
    <a class="n-page" href="?page=6">26-30</a>
    <a class="n-page" href="?page=7">31-35</a>
    <span class="n-current-page">36-40</span>
    <a class="n-page" href="?page=9">41-45</a>
    <a class="n-page" href="?page=10">46-50</a>
</div>

As you can see within getArray result, the keys are not the same as the values, the keys represent the pages numbers(inside the href attribute), the values represent the link name(you can also understand by the name how many rows each page contains).

So after we understand that with '$' method the keys/values are not the same, let me say that when ever you decided to use getArray and iterate yourself always use the keys inside the href attribute and the values as the link names for example:

foreach($Numerator->getArray(8) as $key => $value){
    echo '<a href=?page='.$key.'>'.$value.'</a>';
}

Now when you switch from & to $ or the opposite you won't have to change the foreach loop every time you switch method.

setNumerator

This method will always takes array:

Key Default value Type Accepted values Role
0 0 Integer Bigger than or equal to 0 Left side pages
1 0 Integer Bigger than or equal to 0 Right side pages
2 1 Integer Bigger than 0 Rows per page
3 1 Integer Bigger than 0 Total rows number

The default values will take place if you provide an invalid type or none accepted value

getArray and getHtml

Both methods will always takes integers as the current page number, if the page number you provide is smaller than 1 the default current page is 1, if the page number you provide is bigger than the calculated total pages number(Numerator calculate the total pages number internally) the current page number will become the total pages number.

Rows per page, 5 within [2, 2, 5, 95]

This is the rows number you want to present within each page, you probably saw how websites limit the number of rows presented within each page.

Total rows number, 95 within [2, 2, 5, 95]

You need to count all your rows from your database or any other data source, Numerator needs this value to calculate the total pages number.

Why does Numerator needs the total pages number?, a small example will help you understand.

Until now I've used the following settings array [2, 2, 5, 95]

To calculate the total pages number Numerator will do the following:

$totalPages = (int)ceil($totalRows / $rowsPerPage);

The (int) is not actually neccassery, ceil will do the job, the use of (int) is well explained within the code itself, you can read more about type casting here.

The ceil is in case we have a remainder for example 93 / 5 = 18.6 the result means that we have 18 pages and some more rows, the rows can't go into page 18 because it's full, so ceil is used to round up to 19.

Now when we understand how the calculation works, you need to understand that there are 2 reason for Numerator to know what is the total pages number.

  1. If you provide 10 as the current page number but according to your settings, Numerator calculate your total pages and find out it's 8, well for that kind of case the current page number will become 8.

  2. Numerator needs to know where the current page number is presented among the total pages so it can "figure out" that there may be extra slot/s to the right side, For example if we set 2 pages each side, the current page is 8 and the total pages is 9, well because Numerator know the total pages number it can "figure out" that there is an extra slot on the right side so it can assign it to the left side.

The big question

The big question is a tricky one, after the previous section you may think of it yourself, anyway listen carefully to the following scenario:

Here is our new settings array [3, 3, 5, 10], the current page number is 1 and the total pages number is 2, did you come up with the question yet?, well here it is:

What will happen to the 3 spare slots we have on the left and 2 spare slots we have on the right?

The answer is nothing, Numerator will only use spare slots when possible so the result array is:

[1 => 1, 2 => 2]

What if the settings array is [3, 3, 5, 25], the current page number is 2 and the total pages number is 5, the result array is:

[1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]

Now only the right slots is fully used, the left slots have 2 spare slots but because the total pages is already presented the right side can't use the spare slots from the left side.

If the current page is 4 the opposite scenario will happen, now the left side can't use the right side spare slots because page 1 is already presented, the result array is same as above.

The ampersand method ('&')

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('&');
$Numerator->setNumerator([2, 2, 5, 95]);
echo $Numerator->getHtml(6);

The html result is:

<div class="n-container">
    <a class="n-page" href="?page=4">4</a>
    <a class="n-page" href="?page=5">5</a>
    <span class="n-current-page">6</span>
    <a class="n-page" href="?page=7">7</a>
    <a class="n-page" href="?page=8">8</a>
</div>

The dollar method ('$')

This method is a bit different and special:

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('$');
$Numerator->setNumerator([2, 2, 5, 95]);
echo $Numerator->getHtml(6);

The html result is:

<div class="n-container">
    <a class="n-page" href="?page=4">16-20</a>
    <a class="n-page" href="?page=5">21-25</a>
    <span class="n-current-page">26-30</span>
    <a class="n-page" href="?page=7">31-35</a>
    <a class="n-page" href="?page=8">36-40</a>
</div>

As you can see the link names is much more interesting, they also provide information about the rows number presented in each page.

The errors system

The errors system is extremely friendly, it won't generate an unexpected error.

What is the symptom for an error?, for getArray the returned value is empty array and for getHtml the returned value is empty string.

So how do you know what error is it?, simply by calling getError method which return a string with the error information.

How to use the error system?

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('*'); // Nonexistent method.
$Numerator->setNumerator([2, 2, 5, 95]);
echo $Numerator->getHtml(6); // Empty string will be printed.
echo $Numerator->getError(); // Result: Method not found.

The path system

If you will unzip Numerator.rar you will see Numerator.php under Numerator folder and methods folder.

I aware that at some point you may want to move the methods folder or rename it or maybe just move Numerator.php, and that's the reason for the path system I will explain the base idea.

Lets start with the basic structure:

  • www (The root folder)
    • Numerator (Main numerator folder)
      • Numerator.php (Main numerator file)
      • methods (Numerator methods folder)
        • ampersand.php
        • dollar.php

Lets say you have folder named includes within your www folder and you decided to move the methods folder to includes folder and also rename it to NumeratorIncludes, here is the new structure:

  • www
    • Numerator
      • Numerator.php
    • includes
      • NumeratorIncludes
        • ampersand.php
        • dollar.php

Now we want to "aware" Numerator about the new location for the methods folder(NumeratorIncludes folder):

// Using double dots(..) to go up the folder tree
$Numerator = new \Numerator\Numerator('$', '../includes/NumeratorIncludes');

// Using absolute path (/) to go up to the working directory(www)
$Numerator = new \Numerator\Numerator('$', '/includes/NumeratorIncludes')

When to use absolute path(/) and when to use double dots(..)?

The absolute path will always point to your server root directory, so if Numerator.php is "buried deep" within your root directory use absolute path instead of ../../../etc.

If the methods folder is closer to Numerator.php than from the root directory you should use double dots(..).

The easiest way to figure out the best path is to check both, and pick whichever shorter.

More options

This framework offers more options so for the following scenarios I will use the following settings:

require_once 'Numerator.php';
$Numerator = new \Numerator\Numerator('&');
$Numerator->setNumerator([2,2,5,95]);

Remember that if you'v decided to use getArray its on your responsibility to transform the array into html, all of the following options apply for both getArray and getHtml.

**Notice, ** the following examples are best to be checked with actual styling, so let me provide a basic css styling, for easy testing the output drop the html outputs below with the styling into Plunker or jsfiddle:

a {
    color: #4ea6ea;
}

a:hover {
    text-decoration: none;
}

.n-container
{
    margin-bottom: 10px;
}

.n-page, .n-current-page, .n-prev-next, .n-edges-separator, .n-pages-separator, .download
{
    color: #ffffff;
    text-decoration: none;
    background: #71bc22;
    padding: 4px 8px;
}

.n-page:hover, .n-prev-next:hover, .download:hover
{
    background: #60b508;
}

.n-current-page, .n-edges-separator, .n-pages-separator
{
    background: #4ea6ea;
}

Add previous/next

/* You need to provide array with 2 elements,
 * first element for the previous navigator,
 * second element for the next navigator.
 * */
echo $Numerator->getHtml(8, ['«', '»']);

The html result is:

<div class="n-container">
    <a class="n-prev-next" href="?page=5">«</a>
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
    <a class="n-prev-next" href="?page=11">»</a>
</div>

Add edged pages

/* null as first argument to disable prev/next.
 * string as second argument to activate edged pages.
 * */
echo $Numerator->getHtml(8, null, '...');

The html result is:

<div class="n-container">
    <a class="n-page" href="?page=1">1</a>
    <a class="n-page" href="?page=2">2</a>
    <span class="n-edges-separator">...</span>
    <a class="n-page" href="?page=6">6</a>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-current-page">8</span>
    <a class="n-page" href="?page=9">9</a>
    <a class="n-page" href="?page=10">10</a>
    <span class="n-edges-separator">...</span>
    <a class="n-page" href="?page=18">18</a>
    <a class="n-page" href="?page=19">19</a>
</div>

Add pages separator

/* null as first argument to disable prev/next.
 * null as second argument to disable edged pages.
 * string as the third argument to activate pages separator.
 * */
echo $Numerator->getHtml(5, null, null, '-');

The html result is:

<div class="n-container">
    <a class="n-page" href="?page=6">6</a>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-pages-separator">-</span>
    <span class="n-current-page">8</span>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=9">9</a>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=10">10</a>
</div>

Options combination

// This time all the options activated.
echo $Numerator->getHtml(5, ['«', '»'], '...', '-');

The html result is:

<div class="n-container">
    <a class="n-prev-next" href="?page=13">«</a>
    <a class="n-page" href="?page=1">1</a>
    <a class="n-page" href="?page=2">2</a>
    <span class="n-edges-separator">...</span>
    <a class="n-page" href="?page=6">6</a>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=7">7</a>
    <span class="n-pages-separator">-</span>
    <span class="n-current-page">8</span>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=9">9</a>
    <span class="n-pages-separator">-</span>
    <a class="n-page" href="?page=10">10</a>
    <span class="n-edges-separator">...</span>
    <a class="n-page" href="?page=18">18</a>
    <a class="n-page" href="?page=19">19</a>
    <a class="n-prev-next" href="?page=17">»</a>
</div>

setClasses

If you take a look at the html outputs you could have notice the classes inside the resulted elements, as a default getHtml will add the following classes:

Class name Added on
n-container Div element containing all the elements
n-current-page When the element represent the current page
n-page When the element represent a page
n-edges-separator When the element represent edge separator
n-pages-separator When the element represent page separator

All of those classes can be changed using setClasses method, here is how:

/* We must call setClasses before calling getHtml/getArray,
 * if you send null the default for that key will be used.
 * */
$Numerator->setClasses('cont', 'page', 'active', 'prevNext', 'edgesSep', 'pagesSep');

Let me provide a table so you can understand which argument replace which default:

Key Replace default
0 n-container
1 n-page
2 n-current-page
3 n-prev-next
4 n-edges-separator
5 n-pages-separator

setQueryString

There will be time where you want to append more than just the page to the pagination links for example:

http://example.com/?page=5&lang=en

Or prepend + append a token:

http://example.com/?lang=en&page=5&token=tokenString

The problem is that by default the href attribute for the links returned by getHtml is href="?page=5", so we lose the option to append or prepend any query string to the href attribute, well setQueryString can help us with just that.

Key Default Type Role
0 ''(Empty string) String Prepended string
1 ''(Empty string) String Appended string

So now if we do:

/* We must call setQueryString before calling getHtml/getArray,
 * if you send null the default for that key will be used,
 * if you send empty string error will be raised.
 * */
$Numerator->setQueryString('?lang=en', '&token=tokenString');

For the above example we get href attributes like: href="?lang=en&page=5&token=tokenString", of course you can only set only one of them which result with only appended or prepended string.

That's it guys.

Contact

Feel free to contact me at avielfedida@gmail.com, hope you make the best out this framework.

Version: 1.0
License: MIT