Is pagination impossible or just hard?

I made the switch to Discourse recently and my community is torn on whether they like the infinite scroll or not. Some users like it, some don’t care, some treat it like an existential threat to the community. Based on other discussions I read here it sounds like it’s a common point of contention.

I understand that the developers of this software have no intention of providing pagination as an option. I can respect that. At this point, I’ve written a few plugins and layouts and looked though a bit of the code in the core github so I have a basic familiarity with the software. I’m just wondering how hard it would be to write a plugin for pagination should my community continue to resist? Is it likely that I will have to rewrite a lot of the basic core ruby code? Is it something that can be placed on top of all the existing code that could run seamlessly? Is the database structure really poorly designed for querying in a paginated way?

Just wanted to get a sense of the feasibility of undertaking this task from the people who are most familiar with the code.

1 Like

Dev is not my strong suit, but I think there are pages already if you can make use of them?

Eg. https://meta.discourse.org/t/introducing-discourse-chat-beta/210734/?page=6

2 Likes

I think the main issue you’d have is the constant burden of maintaining a plugin that very regularly broke as you’d have to override a lot of the UI for which only minor changes in core might break.

The issue is unlikely to be technical, almost any one time customisation is possible, more like practical, economic.

If you are still keen: give it a try and let me know if I’m wrong!

Alternatively why not take the easier route of using a forum that is page based, plenty of them?

3 Likes

You mean the implemention of the chat uses pages? Sorry, I dont think I am following.

No, I think I borked it. :slight_smile:

You can append ?page=2 under certain circumstances, but it appears I have forgotten precisely how that works. :slight_smile:

1 Like

AFAIK that parameter works only for pages we serve to crawlers and old, unsupported browsers.

4 Likes

These are the same users are upset that they can’t use their Commodore 64s. Tell them that you are very sorry and that you’re working hard on the problem and do nothing. Infinite scrolling has been industry standard for at least a decade.

Or, you might try to get them to say just why they think they want it (so that they can link to a particular place in the topic, perhaps?) and demonstrate that you can now link to a specific post and not “see the 6th post on this page”. But they’ll still be very unhappy that it’s not exactly the way it was a decade ago.

4 Likes

I think your point here is very strong. Ultimately this plugin would force us to either never update or would be a task that never ends.

As @pfaffman implies, the communication-based solution is probably easier than a technical one.

I have a feeling most of these users will just get used to it. Just wanted to explore different options if they don’t.

I’m still open to more feedback on how (un)feasible this task would from anyone else

2 Likes

The development would cost somewhere upwards of $10k, possibly as much as $50k. Perhaps you could ask your community to find those funds? Oh and give you $5k a year for maintenance … turning a free open-source project into a costly nightmare.

I don’t see the benefit of “paging” much given you can link directly to a Category, Topic or Post?

5 Likes

I do think a “hybrid” component may be somewhat practical.

Every N posts in a topic you insert a “paginator”

Post 1
Post 2 
...
Post 15

[*Page 1*] [Page 2] [Page 3] [Page 4]

Post 16

... 

De-infinite scrolling Discourse is not a practical exercise, but a component that makes a “hybrid” paginator (even with topic list changes) is probably in the 2k-5k range.

1 Like

Sam, your message makes me remind Natural breakpoints or "chapters" for long topics?; I’d be very curious to see a result of something like this. And it could be a good alternative for those who miss pagination. They often seem to miss the pagination because pages are breakpoints and nothing more.

3 Likes

@scottmastro

@ghassan is currently (or recently) developing a pagination plugin:

This seems to be a way to link separate topics rather than adding page navigation to a single topic


I did make a bit of progress on the pagination. The idea was to uses the ?page=x function built into discourse to navigate between “pages” and basically block further messages from being loaded in by overriding the post-stream functions that load in the next batch of posts.

See below for more details (and unresolved issue)

I added pagination buttons at the top and bottom of each topic. One thing I didn’t figure out yet is how to get the total number of pages in a topic so I know how many buttons to display. It’s easy from the back end but I’d prefer this to be a theme component over a plugin so the options of how to do it are more limited.

With these two things, it seems like it would be a mostly functional pagination system. I’m sure there will be some odd behaviours though that will need polishing, like whether deleted posts count as a message on a page or controlling how many posts should be shown when jumping to the last page.

I have been periodically going back to this problem. Not sure if I’ll ever reach a clean solution but I think a hacky-mostly functional solution could exist

3 Likes

To create navigation from Topic to Topic (and auto insert Back/Prev and Forward/Next buttons on each Topic in the sequence), I’m doing it this way

I’m repurposing the “Reply as Linked Topic” and then CSS styling the links like so …

And adding some CSS in the Theme Settings …

MINIMAL CSS JUST FOR THE BUTTONS
.post-links-container {
    margin-left: var(--topic-body-width-padding);
    position: absolute;
    top: 37px;
    right: 30px;
}

.post-links-container ul li .d-icon {
    display: none;
}

.post-links-container .post-links {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.post-links-container .post-links li:last-of-type {
    margin-bottom: 0;
}

.post-links-container ul li a[href] {
    align-items: center;
    border: 1px solid var(--primary-low-mid);
    background: var(--primary-very-low);
    border-bottom-width: 2px;
    border-radius: 3px;
    box-sizing: border-box;
    color: #009a49;
    display: inline-flex;
    font-family: monospace, monospace;
    font-size: var(--font-down-1);
    justify-content: center;
    line-height: var(--line-height-large);
    margin: 0 0.15em;
    min-width: 24px;
    padding: 0.15em 0.6em;
}

.post-links-container ul li a::after {
    content: " ->>";
    padding-left: 0.15em;
}

kbd {
    align-items: center;
    border: 1px solid var(--primary-low-mid);
    background: var(--primary-very-low);
    border-bottom-width: 2px;
    border-radius: 3px;
    box-sizing: border-box;
    color: var(--primary);
    display: inline-flex;
    font-family: monospace, monospace;
    font-size: var(--font-down-1);
    justify-content: center;
    line-height: var(--line-height-large);
    margin: 0 0.15em;
    min-width: 24px;
    padding: 0.15em 0.6em;
}

kbd a {
    padding: 0;
}

kbd a::before {
    content: "<<-";
    padding-right: 0.15em;
}

INSTRUCTIONS AND THE FULL CSS I'M USING

/** Prev and Next Buttons for Books or other Topic Sequencing - this feature is built by repurposing **/
/**   the native Discourse feature "Reply As A Linked Topic" selector in the composer (top left). **/
/** TO SET THIS UP ON YOUR DISCOURSE **/
/** Paste <kbd>%{postLink}</kbd> in /admin/customize/site_texts/js.post.continue_discussion. **/
/** Then create 2 categories: BOOKS (for Blog Style topic sequences) and STORIES (for Regular Topic Style topic sequences). **/
/** Install the https://meta.discourse.org/t/blog-post-styling/110841 theme component **/
/** In the Blog Post Styling Theme Component Settings, assign the BOOKS Category (but not STORIES) as a Blog Category. **/
/** Then create a tag: BOOK and assign that as a Blog Tag in the Blog Post Styling Theme Component Settings **/
/** Then don't forget to paste in the below CSS! It goes in your Theme Header. **/
/** Of course the CSS here will need tweaking to work right in other themes. **/
/** Now you can create sequences of Topics in the STORIES Category which will have the nav buttons, **/
/**   but those Topics will otherwise appear in the Regular Topic Style). **/
/** If you can add the Blog Styling to these STORIES Category Topics by simply adding the BOOK tag. **/
/** A new Topic you compose in the BOOKS CATEGORY using "Reply as a Linked Topic" will already have both the nav buttons **/
/**   as well as the Blog Styling. **/
/** See a Demo at https://meta.discourse.org/t/is-pagination-impossible-or-just-hard/231838/16 **/



.tag-book,
.category-books {
    aside.sidebar,
    .topic-meta-data,
    .tag-book .topic-category .badge-wrapper,
    .category-books .topic-category .badge-wrapper {
    display:none !important;
    
    }
}

.tag-book .container.posts,
.category-books .container.posts {
    justify-content: unset;
    justify-items: unset;
    padding-left: 0;
    display: block;
}

.tag-book .container.posts .topic-post .row,
.category-books .container.posts .topic-post .row {
    display: block;
    justify-content: center;
}

.tag-book #topic-title .title-wrapper,
.category-books #topic-title .title-wrapper {
    display: block;
    margin: 0 auto;
}

.tag-book #topic-title,
.category-books #topic-title {
    display: block;
    margin: 0 auto;
}

.tag-book #topic-title h1,
.category-books #topic-title h1 {
    font-size: 2em;
    padding-right: 20px;
}

.tag-book #post_1 .topic-body,
.category-books #post_1 .topic-body {
    padding-top: 1em;
    border-top: none;
    max-width: 100%;
}

.tag-book #post_1 .topic-body .contents,
.category-books #post_1 .topic-body .contents {
    border-top: none;
    margin-left: 0;
    padding: 0;
}
  
.tag-book p,
.category-books p {
    /* put styles here for the main text in the Book pages */
}

/* Position the Forward button at the top right of the page */
.tag-book .post-links-container,
.category-books .post-links-container {
    margin-left: var(--topic-body-width-padding);
    position: absolute;
    top: 1em;
    right: 30px;
}

/* Position the Back button at the top left of the page */
.category-stories .post-links-container {
    margin-left: var(--topic-body-width-padding);
    position: absolute;
    top: 2.5em;
    right: 30px;
}

/* Remove the link symbol from the Forward button */
.tag-book .post-links-container ul li .d-icon,
.category-books .post-links-container ul li .d-icon,
.category-stories .post-links-container ul li .d-icon {
    display: none;
}

.tag-book .post-links-container .post-links,
.category-books .post-links-container .post-links,
.category-stories .post-links-container .post-links {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.tag-book .post-links-container .post-links li:last-of-type,
.category-books .post-links-container .post-links li:last-of-type,
.category-stories .post-links-container .post-links li:last-of-type {
    margin-bottom: 0;
}

/* Style the Next/Forward button */
.tag-book .post-links-container ul li a[href],
.category-books .post-links-container ul li a[href],
.category-stories .post-links-container ul li a[href] {
    align-items: center;
    border: 1px solid var(--primary-low-mid);
    background: var(--primary-very-low);
    border-bottom-width: 2px;
    border-radius: 3px;
    box-sizing: border-box;
    color: #009a49;
    display: inline-flex;
    font-family: monospace, monospace;
    font-size: var(--font-down-1);
    justify-content: center;
    line-height: var(--line-height-large);
    margin: 0 0.15em;
    min-width: 24px;
    padding: 0.15em 0.6em;
}

/* Add arrows pointing right to the Forward button */
.tag-book .post-links-container ul li a::after,
.category-books .post-links-container ul li a::after,
.category-stories .post-links-container ul li a::after {
    content: " ->>";
    padding-left: 0.15em;
}

/* Alternatively Use an Image for the Right Arrow */
/*
.tag-book .post-links-container::after,
.category-books .post-links-container::after,
.category-stories .post-links-container::after {
    content: url('../../media/arrow-right.svg');
    display: inline-block;
    width: 12px;
    height: 12px;
}
*/

/* Style the Back/Previous button*/
.tag-book kbd,
.category-books kbd,
.category-stories kbd {
    align-items: center;
    border: 1px solid var(--primary-low-mid);
    background: var(--primary-very-low);
    border-bottom-width: 2px;
    border-radius: 3px;
    box-sizing: border-box;
    color: var(--primary);
    display: inline-flex;
    font-size: var(--font-down-1);
    justify-content: center;
    line-height: var(--line-height-large);
    margin: 0;
    min-width: 24px;
    padding: 0.15em 0.6em;
}

.tag-book kbd a,
.category-books kbd a,
.category-stories kbd a {
    padding: 0;
}

/* Add arrows to the back button */
.tag-book kbd a::before,
.category-books kbd a::before,
.category-stories kbd a::before {
    content: "<<-";
    padding-right: 0.15em;
}

/* Alternatively Use an Image for the Left Arrow */
/*
.tag-book kbd a::before,
.category-books kbd a::before,
.category-stories kbd a::before {
    content: url('../../media/arrow-left.svg');
    display: inline-block;
    width: 12px;
    height: 12px;
}
*/


Here’s the result …

You can test it live here …

4 Likes

Yeah I think this is the best way to approach it. If you can find out exactly what they don’t like about infinite scroll it can help steer the conversation to something more productive. If there’s functionality they’re missing then maybe it’s easy to find the equivalent, if there’s something not working about it maybe that’s something we can improve, but if it’s just being opposed to change there’s not much to be done.

2 Likes