Merge pull request #3 from mmacia/master

Adecentamiento del paginador
Merge pull request #4 from mmacia/master

added methods to render a paginator
Merge pull request #5 from mmacia/master

Feature complete push
Merge pull request #6 from mmacia/master

Improved multiple paginators support
Edited README.md via GitHub
Merge pull request #7 from mmacia/master

Error using multiple paginators
Pagination improvements

Changes that I've made:  Added a setter and getter to 'offset' in
Paginator.  Removed services.xml (which before was used just to
Paginator main class).   Described 3 new xmls for services (paginator,
templating and twig). They're loaded by Dependency Injection.
'paginator.xml' it's the same old 'services.xml'. 'templating.xml' is
used to register PagebarHelper and 'twig.xml' is used to register
PaginationExtension.  Implemented 5 twig template files under
Resources/views/Paginator/. This templates are used by PagebarHelper and
have some presentation logic implemented inside them.  Implemented
PagebarHelper under Templating/Helper/ which have methods to generate
pagination content-bar in a default way or very user personalized way.
Implemented PaginationExtension which extends Twig functions. To
register the functions I've used the same nomenclature used by Symfony2
forms. So, you''ll find something like 'pagination_numbers',
'pagination_next', etc. Each of them maps the function to a method
inside the class. This mapped methods are also a mapper, because they
call the same method name from pagebar injected object (PagebarHelper
class). So, the PagebarHelper is who really have templates namespaces
defined and generates a dynamically content. PaginationExtension just
have a definition of who is responsible for that.  ####### HOW TO
#######  Note: I'll base this examples on the same example that you used
on github main page.  # Controller  In public function listAction() from
MyController class, there is no more need to pass $paginator as a view
variable, so you just use:   $vars = array('users' => $users);  #
Understanding the extension  Twig was extended to support new functions
inside your view. This functions is all that you'll need to do whatever
you want.   Here is the list of functions supported by now, followed by
their descriptions:    1. pagination_first()    Return a first link
OPTIONS     tag: The tag wrapping tag you want to use (default: 'span')
disabledTitle: Title when the link is disabled     disabledClass: Class
when the link is disabled    PARAMETERS:     routeName: [required]
string: Your controller route name (alias)     title: [optional] string:
Label for the link (default: '<< First')     options: [optional] array:
See options above (in twig view you use a hashmap)     paginatorId:
[optional] string: your paginator Id (if you use the multiple paginate
feature)    2. pagination_prev()    Return a link to previous page
OPTIONS     tag: The tag wrapping tag you want to use (default: 'span')
disabledTitle: Title when the link is disabled     disabledClass: Class
when the link is disabled    PARAMETERS:     routeName: [required]
string: Your controller route name (alias)     title: [optional] string:
Label for the link (default: '< Prev')     options: [optional] array:
See options above (in twig view you use a hashmap)     paginatorId:
[optional] string: your paginator Id (if you use the multiple paginate
feature)      3. pagination_numbers()    Returns a set of numbers for
the paged result set uses a modulus to decide how many numbers to show
on each side of the current page    OPTIONS     tag: The tag wrapping
tag you want to use (default: 'span')     currentClass: The class name
to assign to your tag on current page number (default: 'current')
modulus: how many numbers to include on either side of the current page
(default: 8)     separator: Separator content between numbers (default:
'|')     first: Whether you want first links generated, set to an
integer to define the number of 'first' links to generate (default: 0)
last: Whether you want last links generated, set to an integer to define
the number of 'last' links to generate (default: 0)    PARAMETERS:
routeName: [required] string: Your controller route name (alias)
options: [optional] array: See options above (in twig view you use a
hashmap)     paginatorId: [optional] string: your paginator Id (if you
use the multiple paginate feature)    4. pagination_next()    Return a
link to next page    OPTIONS     tag: The tag wrapping tag you want to
use, defaults to 'span'     disabledTitle: Title when the link is
disabled     disabledClass: Class when the link is disabled
PARAMETERS:     routeName: [required] string: Your controller route name
(alias)     title: [optional] string: Label for the link (default: 'Next
>')     options: [optional] array: See options above (in twig view you
use a hashmap)     paginatorId: [optional] string: your paginator Id (if
you use the multiple paginate feature)      5. pagination_last()
Return a last link    OPTIONS     tag: The tag wrapping tag you want to
use, defaults to 'span'     disabledTitle: Title when the link is
disabled     disabledClass: Class when the link is disabled
PARAMETERS:     routeName: [required] string: Your controller route name
(alias)     title: [optional] string: Label for the link (default: 'Last
>>')     options: [optional] array: See options above (in twig view you
use a hashmap)     paginatorId: [optional] string: your paginator Id (if
you use the multiple paginate feature)      6. pagination_counter()
Returns a counter string for the paged result set    Generates a default
output like:       'Page 13 of 40, showing 3 records out of 119 total,
starting on record 37, ending on 39'    PARAMETERS:     format:
[optional] string: The format string you want to use       To set this
custom string use the following placeholders inside your string:
'0x0age, 0x7fff70e53630ages, 0urrent, 0ount, tart, 0.000000e+00nd' and
any custom content you would like     paginatorId: [optional] string:
your paginator Id (if you use the multiple paginate feature)       7.
pagination_offset()    Return the relative index to current offset
PARAMETERS:     index: [optional] integer: Your current iterator index,
in twig you can use 'loop.index'     paginatorId: [optional] string:
your paginator Id (if you use the multiple paginate feature)      8.
pagination_offset0()    Return the relative index to current offset
using a start zero index parameter    PARAMETERS:     index: [optional]
integer: Your current iterator index, in twig you can use 'loop.index0'
paginatorId: [optional] string: your paginator Id (if you use the
multiple paginate feature)    # How to render the pagination bar in your
twig view  Just render your table and rows normally. For example, using:
{ for user in users } FOO { endfor }   After that:    ##### SPAN EXAMPLE
#####  Put the following for a default 'span' based bar layout:   {{
pagination_counter('You\'re on page 0x7fff70e53630age of 0x7fff70e53630ages')
}}   <div class="pagination">    {{ pagination_first('user_index') }}
{{ pagination_prev('user_index') }}     {{
pagination_numbers('user_index') }}        {{
pagination_next('user_index') }}     {{ pagination_last('user_index') }}
</div>    Inside your <head> you may want to use some style on this
pagination, here is a example:      <style type="text/css">
.pagination {margin-top:15px; float:right;}    .pagination span
{list-style:none;}    .pagination span {float:left; margin-left:7px;
_display:inline; font-size:11px;}    .pagination span a {color:#666;
text-decoration:none;}    .pagination span a:hover,    .pagination span
.current {color:#CCC;}    .pagination span .disabled {display:none;}
</script>     This will output something like:   << First < Prev 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21
Next > Last >>     Now let's try to use a UL LI pagination bar:    #####
UL LI EXAMPLE ######  Put the following for a 'li' based bar layout:
{{ pagination_counter('You\'re on page 0x7fff70e53630age of 0x7fff70e53630ages')
}}   <div class="pagination">     <ul>      {{
pagination_first('log_index', null, {'tag':'li'}) }}      {{
pagination_prev('log_index', null, {'tag':'li'}) }}      {{
pagination_numbers('log_index', {'tag':'li', 'separator':''}) }}
{{ pagination_next('log_index', null, {'tag':'li'}) }}      {{
pagination_last('log_index', null, {'tag':'li'}) }}     </ul>   </div>
The same above style modified to ul li:       <style type="text/css">
.pagination {margin-top:15px; float:right;}     .pagination ul li
{list-style:none;}     .pagination ul li {float:left; margin-left:7px;
_display:inline; font-size:11px;}      .pagination ul li a {color:#666;
text-decoration:none;}     .pagination ul li a:hover,     .pagination ul
.current {color:#CCC;}     .pagination ul .disabled {display:none;}
</script>   This will output something like:       << First < Prev 5 6 7
8 9 10 11 12 13 14 15 16 17 18 19 20 21 Next > Last >>    # More
customization examples   # Counter message  Instead of: {{
pagination_counter('You\'re on page 0x7fff70e53630age of 0x7fff70e53630ages')
}}  Use: {{ pagination_counter() }}  Output will be the default: 'Page
13 of 40, showing 3 records out of 119 total, starting on record 37,
ending on 39'    # Multiple pagination  Suppose that in your controller
you've defined a ID for your paginator like:
$paginator->setItemsPerPage(3, 'users');   $users =
$paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL(),
'users')->getResult();   $paginator->setItemsPerPage(3, 'groups');
$groups =
$paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL(),
'groups')->getResult();      $vars = array(          'users'     =>
$users,          'groups'    => $groups);      return
$this->render('MyBundle:User:list.html.twig', $vars);    *** Notice that
you don't need to pass 'paginator' from your controller to your view as
$vars (don't matter if it's multiple or single pagination).     In your
view pagination functions, you'll need to define this ID (look at the
documentation above to know the argument number)  Instead of:    {{
pagination_first('log_index', null, {'tag':'li'}) }}    {{
pagination_prev('log_index', null, {'tag':'li'}) }}    {{
pagination_numbers('log_index', {'tag':'li', 'separator':''}) }}
{{ pagination_next('log_index', null, {'tag':'li'}) }}    {{
pagination_last('log_index', null, {'tag':'li'}) }}   Use:   {{
pagination_first('log_index', null, {'tag':'li'}, 'users') }}    {{
pagination_prev('log_index', null, {'tag':'li'}, 'users') }}    {{
pagination_numbers('log_index', {'tag':'li', 'separator':''}, 'users')
}}       {{ pagination_next('log_index', null, {'tag':'li'}, 'users') }}
{{ pagination_last('log_index', null, {'tag':'li'}, 'users') }}      #
Using offset to generate a relative ordered index   <table
class="records_list">             <thead>     <tr>      <th>#</th>
<th>Name</th>                  <th>Email</th>              </tr>
</thead>    <tbody>    { for user in users }     <tr>      <td>{{
pagination_offset(loop.index) }}</td>      <td>{{ user.name }}</td>
<td>{{ user.email }}</td>     </tr>     { endfor }    </tbody>
</table>  Output will be a index # like: 1,2,3,4,5 on first page.
6,7,8,9,10 on second page, and so on.  Other usage example: {{
pagination_offset0(loop.index0) }}  Output will be the same.   What if
I'm using multiple pagination in the same view? Just add the paginator
ID as parameter:   {{ pagination_offset(loop.index, 'users') }}     #
Changing the MODULUS  Modulus represents a integer N which will be the
number of pages displayed before current and after current.  Default
value is 8. So if you are on page 9 you get:   << First <Prev 1 2 3 4 5
6 7 8 9 10 11 12 13 14 15 16 17 Next > Last >>     Lets change modulus
to 3, instead of: {{ pagination_numbers('log_index', {'tag':'li',
'separator':''}) }}        Use: {{ pagination_numbers('log_index',
{'tag':'li', 'separator':'', 'modulus':3}) }}  Output for page 10 will
be:   << First < Prev 7 8 9 10 11 12 13 Next > Last >>     # Showing
2-first and 3-last pages  Instead of:  {{
pagination_numbers('log_index', {'tag':'li', 'separator':'',
'modulus':3}) }}  Use: {{ pagination_numbers('log_index', {'tag':'li',
'separator':'', 'modulus':3, 'first':2, 'last':3}) }}  Output will be:
<< First < Prev 1 2 7 8 9 10 11 12 13 38 39 40 Next > Last >>    #
Defining a separator (using the above example of 2-first and 3-last
pages)  Good practices says to define in your stylesheet a separator for
a UL LI based list. That's why our seperator is ''.  But suppose we
define anything else, like '-' as seperator:   {{
pagination_numbers('log_index', {'tag':'li', 'separator':'-',
'modulus':3, 'first':2, 'last':3}) }}  In this case you'll get:   <<
First < Prev 1 - 2 ... 7 - 8 - 9 - 10 - 11 - 12 - 13 ... 38 - 39 - 40
Next > Last >>  Notice that the separator between numbers is '-' but
'...' separates 'first' and 'last' from 'numbers'.  If you don't define
separator, the default separator will be a pipe '|'.    # Changing
labels   Instead of:    {{ pagination_first('log_index', null,
{'tag':'li'}) }}     {{ pagination_prev('log_index', null, {'tag':'li'})
}}     {{ pagination_numbers('log_index', {'tag':'li', 'modulus':3,
'first':3, 'last':3}) }}        {{ pagination_next('log_index', null,
{'tag':'li'}) }}     {{ pagination_last('log_index', null, {'tag':'li'})
}}   Use:    {{ pagination_first('log_index', '<<', {'tag':'li'}) }}
{{ pagination_prev('log_index', '<', {'tag':'li'}) }}     {{
pagination_numbers('log_index', {'tag':'li', 'separator':'','modulus':3,
'first':3, 'last':3}) }}        {{ pagination_next('log_index', '>',
{'tag':'li'}) }}     {{ pagination_last('log_index', '>>', {'tag':'li'})
}}   Output will be:       << < 1 2 3 7 8 9 10 11 12 13 38 39 40 > >>
# Defining a disabled Title and Class   In this example we've used a CSS
with: .pagination ul .disabled {display:none;}   Since first, prev, next
and last adds by default 'disabled' to its tags.   So, if you're on page
1 the output will be:       1 2 3 4 38 39 40 > >>   If you remove this
entry in your CSS, you'll get:    << < 1 2 3 4 38 39 40 > >>   Notice
that << and < will be displayed, but will not be a link.      Now, try
the following code:    {{ pagination_first('log_index', '<<',
{'tag':'li', 'disabledTitle':''}) }}     {{ pagination_prev('log_index',
'<', {'tag':'li', 'disabledTitle':''}) }}    The output will be:    1 2
3 4 38 39 40 > >>      In the CSS, add again: .pagination ul .disabled
{display:none;}   Instead of: .pagination ul .disabled {display:none;}
Use: .pagination ul .off {display:none;}      And use the following code
in view:    {{ pagination_first('log_index', '<<', {'tag':'li',
'disabledClass':'off'}) }}     {{ pagination_prev('log_index', '<',
{'tag':'li', 'disabledClass':'off'}) }}    The output will continue to
be:    1 2 3 4 38 39 40 > >>    # Simpler bar   Of course you don't need
to call all this functions, it depends from the result you may want.
Try to use:    <div class="pagination">      <ul>       {{
pagination_prev('log_index', null, {'tag':'li'}) }}       {{
pagination_numbers('log_index', {'tag':'li',
'separator':'','modulus':3}) }}          {{ pagination_next('log_index',
null, {'tag':'li'}) }}      </ul>    </div>   The output on page 5 will
be a simple:       < Prev 2 3 4 5 6 7 8 Next >
Extension refactored. I have deleted use Definition
Style changes
README permissions 0644
IdeupSimplePaginatorBundle.php permissions changed
Making general view
Added gitignored
Adding Test structure
complete basic render. simple_paginator_render
clean code
twig render complete
first Page and last Page
Adapters and twig views
Create new Adapter Factory