Page MenuHomePhabricator

Results pagination
Open, MediumPublicFeature

Description

Feature summary (what you would like to be able to do and where): Paginate the results of a search or query. This includes both the main search results and the results of the search for works by an author.

Benefits (why should this be implemented?): This can be very useful when the list of results is too long, especially since Paulina's homepage search engine recently added the ability to perform generic queries for authors by country or works by discipline.

Event Timeline

Pepe_piton triaged this task as Medium priority.Jul 29 2025, 7:31 PM

Hello @Pepe_piton , I would like to work on this issue, can you please assign to me?

Sure @OlusegunFaj. I assigned it to you. Go ahead. Thanks!

@Nat_WDU @Pepe_piton kindly review!

Changes made:

  1. Creation of Previous and Next button. Both on Author and Works Results page. On the first page, "Previous" button remains disabled, and likewise on the last page, "Next" remains disabled.
  2. If someone tries to enter a page no. which is a negative number, of a number greater than the total no of pages, they are redirected to first and last page respectively.
  3. No. of results per page is limited to 10.
  4. The button design is coherent with the rest of the elements on the page.

PR: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/16
Changes preview:

Hello @Pepe_piton

I've completed this task and created a merge request: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/30

The implementation adds pagination to both search results pages and author works lists with 50 items per page.

Note: All search filters (gender, nationality, type_of_work, country_of_origin) are preserved when navigating between pages. The "in-public-domain" filter is not currently preserved across pagination due to Jinja2 template limitations with parameter names containing hyphens. If this needs to be addressed, I can implement a workaround.

Ready for review!

@Pepe_piton @Nat_WDU I've worked on this feature for both author search and work list search. I'm now waiting for my account to be approved as a contributor so me to create a PR.

Here is the link to my MR:
https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/40

Screenshot

Screenshot 2025-10-10 at 13.41.34.png (1×1 px, 210 KB)

@Pepe_piton @Nat_WDU I have implemented pagination plus added extra functionalities surrounding the feature. Here is a summary:
Changes Made:

  • Added page-based navigation to results.
  • Users can now view results page by page.
  • The template displays Page X of Y at both the top and bottom of the results page.
  • If one wants to go to a specific page, they can type it in the browser's search bar.
  • Prevents "Page not found" errors when navigating beyond available results.
  • Updated Warning Message for Large Result Sets: Your search returned too many results. All results are not being shown. Please refine your search.

Here is the Merge request: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/61

@Pepe_piton @Nat_WDU

I took my time working on this task. Initially, I planned to implement the pagination logic directly in the main SPARQL query. However, I realized that the results are fetched from the Wikidata API (wikidata.org), so I implemented it using a utility function instead.

  • I have a utility function for the pagination logic
  • I added pagination controls as well as a "Go to page" button, which allows direct navigation to any page
  • When navigating search/works-list pages, the filters (e.g language) persist across those pages.
  • I considered using AJAX to update only the HTML content without reloading the entire page when switching pages of a search/works-list page. I'd love to hear your thoughts on that approach.

Here's my PR: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/120. I'd really love your feedback

Thanks!

@Pepe_piton @Nat_WDU

I took my time working on this task. Initially, I planned to implement the pagination logic directly in the main SPARQL query. However, I realized that the results are fetched from the Wikidata API (wikidata.org), so I implemented it using a utility function instead.

  • I have a utility function for the pagination logic
  • I added pagination controls as well as a "Go to page" button, which allows direct navigation to any page to the markups
  • When navigating search/works-list pages, the filters (e.g language) persist across those pages.
  • I considered using AJAX to update only the HTML content without reloading the entire page when switching pages of a search/works-list page. I'd love to hear your thoughts on that approach.

Here's my PR: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/120. I'd really love your feedback

Thanks!

Nice one @Sopzy

Hi everyone!

Really glad to be sending a Merge Request for this task.
Phew, it has been a real struggle to make pagination work and look somewhat nice ^^

I had to:

  • Understand how to add query parameters to the URL
  • Implement a correct formula to offset the results by 10
  • Not to use plural at all in my variables (if you know, you know :D)
  • Making sure that all the variables from app.py are being returned so I can use them in results.html

Looking forward to your feedback and comments: @Pepe_piton and @Nat_WDU

Edit: I also wanted to share with you an error that I've had coming up multiple times from the updateDropdown function inside the <script> tag in layout.hml (see picture attached).
It came up multiple times while I was trying to implement the pagination, even though I was only working on app.py and results.html files.

I am not sure what the issue was, but I guess it was due to the empty value of dropdown.innerHTML or possibly an incorrect URL I was sending...

Error message :

Screenshot 2025-10-17 18.55.28.png (212×623 px, 42 KB)

Has anyone encountered this error?

@Pepe_piton @Nat_WDU

I took my time working on this task. Initially, I planned to implement the pagination logic directly in the main SPARQL query. However, I realized that the results are fetched from the Wikidata API (wikidata.org), so I implemented it using a utility function instead.

  • I have a utility function for the pagination logic
  • I added pagination controls as well as a "Go to page" button, which allows direct navigation to any page to the markups
  • When navigating search/works-list pages, the filters (e.g language) persist across those pages.
  • I considered using AJAX to update only the HTML content without reloading the entire page when switching pages of a search/works-list page. I'd love to hear your thoughts on that approach.

Here's my PR: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/120. I'd really love your feedback

Thanks!

Nice one @Sopzy

Thanks

Hi everyone!

Really glad to be sending a Merge Request for this task.
Phew, it has been a real struggle to make pagination work and look somewhat nice ^^

I had to:

  • Understand how to add query parameters to the URL
  • Implement a correct formula to offset the results by 10
  • Not to use plural at all in my variables (if you know, you know :D)
  • Making sure that all the variables from app.py are being returned so I can use them in results.html

Looking forward to your feedback and comments: @Pepe_piton and @Nat_WDU

Edit: I also wanted to share with you an error that I've had coming up multiple times from the updateDropdown function inside the <script> tag in layout.hml (see picture attached).
It came up multiple times while I was trying to implement the pagination, even though I was only working on app.py and results.html files.

I am not sure what the issue was, but I guess it was due to the empty value of dropdown.innerHTML or possibly an incorrect URL I was sending...

Error message :

Screenshot 2025-10-17 18.55.28.png (212×623 px, 42 KB)

Has anyone encountered this error?

Could you please share a screenshot of the error?

Sorry @Sopzy I didn’t attach the file properly…
You should be able to view it now!

Hi everyone!

Really glad to be sending a Merge Request for this task.
Phew, it has been a real struggle to make pagination work and look somewhat nice ^^

I had to:

  • Understand how to add query parameters to the URL
  • Implement a correct formula to offset the results by 10
  • Not to use plural at all in my variables (if you know, you know :D)
  • Making sure that all the variables from app.py are being returned so I can use them in results.html

Looking forward to your feedback and comments: @Pepe_piton and @Nat_WDU

Edit: I also wanted to share with you an error that I've had coming up multiple times from the updateDropdown function inside the <script> tag in layout.hml (see picture attached).
It came up multiple times while I was trying to implement the pagination, even though I was only working on app.py and results.html files.

I am not sure what the issue was, but I guess it was due to the empty value of dropdown.innerHTML or possibly an incorrect URL I was sending...

Error message :

Screenshot 2025-10-17 18.55.28.png (212×623 px, 42 KB)

Has anyone encountered this error?

I think this happens when the JavaScript tries to access an element (like the combobox or dropdown) that doesn’t exist on the current page. Since layout.html includes that script globally, it runs on every page, even ones that don’t have the combobox markup.

Can you try wrapping the logic in a check like this:

const dropdown = document.getElementById("country-origin-dropdown");
if (dropdown) {

updateDropdown();

}

I think the error is showing up because of the script execution order.

@Oluwatumininu.m : Oh that makes sense now! Thank you for this!

If I understand correctly: when my code wasn't right, it will go straight to except: abort(404) and display the 404 error page.
However, because the <script> was still executing and calling the updateDropdown() function, it throws that TypeError because it couldn't find the dropdown in the page.
Is that right?

@Oluwatumininu.m : Oh that makes sense now! Thank you for this!

If I understand correctly: when my code wasn't right, it will go straight to except: abort(404) and display the 404 error page.
However, because the <script> was still executing and calling the updateDropdown() function, it throws that TypeError because it couldn't find the dropdown in the page.
Is that right?

Yeahh. When the route hit the abort(404), the 404 page rendered, but the script was still trying to run updateDropdown() from the main layout which doesn’t have the dropdown element. So it ended up throwing a TypeError since it couldn’t find the element on that page.

Ok! Thank you @Oluwatumininu.m ! I understand better now what was happening.

Ok! Thank you @Oluwatumininu.m ! I understand better now what was happening.

Anytime 🙌🙌

Ok! Thank you @Oluwatumininu.m ! I understand better now what was happening.

Anytime 🙌🙌

Have you been able to resolve the issue now ?

Also, ensure that your page is fully loaded before calling your script

@Sopzy:

Yes, it has been resolved!
It happened when I was working on the task.
Most of the times due to me forgetting a 's' at the end of some variables.

Good evening @Pepe_piton, @Nat_WDU and @DidiCoronel
i made a merge request related this issue:-https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/145
Changes made:-

  • Added JavaScript to implement client-side pagination for search results.
  • Displayed 10 items per page with dynamic previous/next and numbered page buttons.
  • Styled pagination buttons using Bootstrap classes and custom CSS.

Please check my work and share feedback so I can improve.

@Nat_WDU @Pepe_piton kindly review!

Changes made:

  1. Creation of Previous and Next button. Both on Author and Works Results page. On the first page, "Previous" button remains disabled, and likewise on the last page, "Next" remains disabled.
  2. If someone tries to enter a page no. which is a negative number, of a number greater than the total no of pages, they are redirected to first and last page respectively.
  3. No. of results per page is limited to 10.
  4. The button design is coherent with the rest of the elements on the page.

PR: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/16
Changes preview:

@shreya-bhagat, pagination on search results looks good. I noticed there's no pagination on works-list which is also part of the task.

Hello @Pepe_piton

I've completed this task and created a merge request: https://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/30

The implementation adds pagination to both search results pages and author works lists with 50 items per page.

Note: All search filters (gender, nationality, type_of_work, country_of_origin) are preserved when navigating between pages. The "in-public-domain" filter is not currently preserved across pagination due to Jinja2 template limitations with parameter names containing hyphens. If this needs to be addressed, I can implement a workaround.

Ready for review!

@System625, pagination logic looks solid. Can you give a few details about the workaround to keep the "in-public-domain" filter?
I did find the pagination buttons on the bottom instead of on top a bit harder to find but UX is not my field. Just a comment in case you want to mention if it was an explicit choice.

@System625, pagination logic looks solid. Can you give a few details about the workaround to keep the "in-public-domain" filter?
I did find the pagination buttons on the bottom instead of on top a bit harder to find but UX is not my field. Just a comment in case you want to mention if it was an explicit choice.

Thanks for the review @DidiCoronel

About the In-Public-Domain Filter Workaround

There are two possible approaches to preserve the "in-public-domain" filter across pagination:

I can rename the parameter from in-public-domain to in_public_domain (hyphen to underscore). This would require:

  • Updating the form input name in templates/layout.html
  • Updating the parameter retrieval in app.py
  • Updating search.py to use the new parameter name

Or I can build the URL manually. Instead of using url_for() in the template, I can manually construct the pagination URLs by appending all query parameters.

I think the former is the best option as it's simpler, more maintainable and makes the codebase more consistent (other parameters already use underscores). The second option preserves the current parameter name but is more error-prone and harder to maintain.

So for the pagination Button Placement

The bottom placement was a decision I made based on following common web patterns (like Google search results) where pagination appears after the content. Another reason is because I limited the search results on a page from 200 to 50 at a time which is suitable for bottom pagination. However, I can add pagination controls at both the top and bottom of the results list and increase the search results back to 200 if that would improve usability. This is actually quite common on sites with long result lists which looking at it now, Paulina falls under the category.

Let me know your preferences and I'll update the MR accordingly!

Hi @Pepe_piton @Nat_WDU @DidiCoronel

I just worked on this task and would love a feedback if possible. Here's my [[ ttps://gitlab.wikimedia.org/toolforge-repos/paulina/-/merge_requests/160 | merge request ]].

Thank you.