Bonjour les grafikartésiens,

Je viens à vous avec une question d'optimisation et de confort.
Je vais essayer d'être le plus concis possible. o/

Ce que je fais

J'ai crée une fonction qui affiche un à un des chapitres issus d'une base de donnée.
Chapitre 1,
Chapitre 2,
Chapitre 3
...

Le système est grossièrement comme ceci, ce qui donne une fausse pagination :

(Lien vers le chapitre précédent) Texte du chapitre actuel (lien vers le chapitre suivant)

Si cela aide, voici mon controller et ma vue :

class ContextController extends AbstractController
    {
        /**
         * @Route("/context/chapter-{chapter}", name="context.index")
         * @param ContextRepository $contextRepository
         * @param int               $chapter
         * @return \Symfony\Component\HttpFoundation\Response
         */
        public function index(ContextRepository $contextRepository, int $chapter)
        {
            $chapters        = $contextRepository->findAll();
            $current_chapter = $contextRepository->find($chapter);
            $others_chapters = $contextRepository->findRand($current_chapter, 2);

            if (is_null($current_chapter)) :
                return $this->redirectToRoute('context.index', [
                    'chapter' => $contextRepository->find(1)->getId()
                ], 301);
            endif;

            return $this->render('context/index.html.twig', [
                'current' => $current_chapter,
                'others' => $others_chapters,
                'chapters' => $chapters
            ]);
        }
    }
<section class="context-banner">
            {% for chapter in chapters if chapter.id is same as (current.id) %}
                {% if current.id is not same as (loop.index) %}
                    <div>
                        <a href="{{ path('context.index', {'chapter': current.id - 1 }) }}" class="context-arrow">
                            &laquo;
                        </a>
                    </div>
                {% else %}
                    <span class="context-arrow-x">&laquo;</span>
                {% endif %}

                {% if current.id is not same as (chapters|length) %}
                    <a href="{{ path('context.index', {'chapter': current.id + 1 }) }}" class="context-arrow">
                        &raquo;
                    </a>
                {% else %}
                    <span class="context-arrow-x">&raquo;</span>
                {% endif %}
            {% endfor %}
        </section>

Ce que je veux

Mon code marche parfaitement. Mais j'aimerai le rendre plus intelligent qu'une simple incrémentation ou décrémentation de l'ID du chapitre en cours. J'ai peur que si un jour je viens à modifier/supprimer un chapitre, comme la fonction ne fait qu'un bête +1 ou -1, je me retrouve avec un 404 not found entre deux chapitres.
Je viens donc voir si quelqu'un a une idée me permettant de faire une itération plus intelligente dans la liste des chapitres (voire même plus poussé encore où lorsque revient en arrière au chapitre 1, il ramène au dernier chapitre de la liste) plutôt que ce système truqué.

Je vous remercie. :)

7 réponses


Hello,

Tu as KnpPaginatorBundle qui fait ça très bien...

Sur mon site sous Symfony avec une liaison entre deux tables, KnpPaginatorBundle ne marche pas et je ne comprends pas pourquoi :(

Bonsoir.
@Nin1363: Excuses-moi, mais quel est le rapport entre ton problème et ce sujet ?
L'auteur du sujet ne parle ni du Bundle, ni d'une relation entre deux tables.
Tu as déjà créé un sujet concernant ton problème, donc attends que quelqu'un y réponde, au lieu d'étendre ton problème dans les sujets des autres dès que tu penses que leur sujet peut être lié au tien.

Pardon ...... C'est de parler de "KnpPaginatorBundle qui fait çà très bien" qui m'a fait réagir...... Désolée :(

Hey, je vois que ça remue ici haha.

Pour faire simple, j'ai testé knpPaginator. Je n'ai rien contre lui. Il marche très bien. Mais il n'offre pas la solution que je veux avec sa pagination (ou alors je suis une bille et je ne sais pas du tout comment le personnaliser).

Je ne pense pas que la solution puisse se porter sur le Bundle cité, tout du moins pas sans une modification dans ta table.
Ce qu'il te faudrait, c'est une représentation intervalaire, de manière à ce que tes chapitres puissent être ordonnés, ce qui te permettrait de pouvoir récupérer plus facilement directement les enregistrement directs contournant le chapitre affiché.
Je te conseille donc vivement de visionner le tutoriel, afin que tu comprennes le principe.

@Talenvni,

Ai-je bien compris ce que tu veux faire? Afficher une pagination restreinte à :
Lien vers chapitre précédent > chapitre en cours > Lien vers chapitre suivant
Si c'est bien cela, et que tu as encore sous le coude ton code intégrant Knp Paginator, tu peux surchager le template Pagination/sliding.html.twig, en modifiant :

{# default Sliding pagination control implementation #}

{% if pageCount > 1 %}
<div class="pagination">
    {% if first is defined and current != first %}
        <span class="first">
            <a href="{{ path(route, query|merge({(pageParameterName): first})) }}">&lt;&lt;</a>
        </span>
    {% endif %}

    {% if previous is defined %}
        <span class="previous">
            <a href="{{ path(route, query|merge({(pageParameterName): previous})) }}">&lt;</a>
        </span>
    {% endif %}

    {% for page in pagesInRange %}
        {% if page != current %}
            <span class="page">
                <a href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>
            </span>
        {% else %}
            <span class="current">{{ page }}</span>
        {% endif %}

    {% endfor %}

    {% if next is defined %}
        <span class="next">
            <a href="{{ path(route, query|merge({(pageParameterName): next})) }}">&gt;</a>
        </span>
    {% endif %}

    {% if last is defined and current != last %}
        <span class="last">
            <a href="{{ path(route, query|merge({(pageParameterName): last})) }}">&gt;&gt;</a>
        </span>
    {% endif %}
</div>
{% endif %}

Par :

{% if pageCount > 1 %}
    <div class="pagination">
        {# Lien vers dernier chapitre si on est au premier#}
        {% if first is defined and current is same as(first) %}
            {% if last is defined %}
                <span class="last">
                    <a href="{{ path(route, query|merge({(pageParameterName): last})) }}">Chapter prev</a>
                </span>
            {% endif %}
        {# Sinon, lien vers le chapitre précédent #}    
        {% else %}
            {% if previous is defined %}
                <span class="previous">
                    <a href="{{ path(route, query|merge({(pageParameterName): previous})) }}">Chapter prev</a>
                </span>
            {% endif %}
        {% endif %}

        {# Chapitre actuel #}
        <span class="current">Actual chapter</span>

        {# Lien vers le premier chapitre si on est sur le dernier #}
        {% if last is defined and current is same as(last) %}
            {% if first is defined %}
                <span class="last">
                    <a href="{{ path(route, query|merge({(pageParameterName): first})) }}">Chapter next</a>
                </span>
            {% endif %}
        {# Sinon, lien vers le chapitre suivant#}
        {% else %}
            {% if next is defined %}
                <span class="next">
                    <a href="{{ path(route, query|merge({(pageParameterName): next})) }}">Chapter next</a>
                </span>
            {% endif %}
        {% endif %}
    </div>
{% endif %}

C'est du vite fait donc à personnaliser et à optimiser mais c'est l'idée...