Adding previous/next buttons (for blog-entry batches)

I know this has been discussed before and I’ve tried using Wizard Nav but it isn’t working for me. It’s most probably me, not the script.

I have a tiddler named Blog, which also uses a tag named Blog. The content of the tiddler is as follows:

<$list filter="[tag[Blog]!sort[created]limit[10]]">
  <div class="blog">
  <h2><$link/></h2>
  <p style="font-weight: bold; font-style: italics;"><$view field="created" format="date" template="DD MMM YYYY" /></p>
  <$transclude mode="block"/>
  </div>
</$list>

This makes a nice blog page, showing the last 10 tiddlers. Naturally, I need to be able to move to the next page of 10 tiddlers, and move back and forth in the same manner. This means I need “next” and “previous” buttons, preferably at the bottom of the Blog page, but I’m flexible.

I don’t know if Wizard Nav will do this for me. I’ve installed it. I have changed the configurable name to Blog and I changed the order to “created”. But nothing appears to happen. Am I missing a step or am I meant to do something else too?

Any help/direction would be appreciated please.

1 Like

@Scribs there are a few options around and hopefully someone will help you with that. I am just replying because I am looking at making something similar to use next/previous on tiddlers that use any tag and one of the reasons I raised this question Do you use a tags tiddler and how?

  • Hopeful in the near term I will have a solution that would satisfy your request but most likely not for a few days.
  • Most likely I will add it to my reimagine tags package and the options will be available on the tag pill, in your case blog tag. However with you in mind I will look at making them available as viewToolbar buttons, as well.
  • How would you like next and previous to appear and where?

Your task here is totally different from what a “next” button would usually do, since a next button gets another tiddler from a list, but you (probably?) don’t have a separate tiddler to get posts 11-20, or 21-30, etc. Of course, one solution would be to make such tiddlers, and tag them with something (like BlogSets) and then the Wizard Nav could go to work on that tag.

But a more elegant solution involves using some kind of variable or field value for the starting value (defaulting to 0), then adjust your list filter like so…

[tag[Blog]!sort[created]butfirst{!!startval}limit[10]]

Then your “next” button would include a setfield action to add 10 to that startval field; a separate “previous” button would subtract 10 from the starval field (and would only show up iff the starval is greater than 0)

I’m sorry I’m not fast enough to provide the full code quickly, but the concepts might be enough to get you started…

1 Like

I poked around to draft a version you can try out at tiddlywiki.com, and modify to taste…

Note that this version builds in a variable for the topic (assuming this is a tag), and an ability to change your preferred inteval (how many appear on a page).

Extra explanatory text appears, so that you can see what the buttons and actions are supposed to do.

I’m sure there are ways this could be optimized, but I hope it helps you envision how this kind of navigation might work.


<$let topic="Community" blogcount={{{ [tag<topic>!sort[created]count[]] }}} interval=5>

Items tagged __<<topic>>__ from <$text text={{{ [{$:/blog-startval}] }}}/> to <$text text={{{ [{$:/blog-startval}add<interval>subtract[1]] }}}/> (of <<blogcount>> total):

{{{ [tag[Community]sort[title]butfirst{$:/blog-startval}limit<interval>]}}}

<hr>

<$list filter="[{$:/blog-startval}compare:number:gt[1]]">
<$button>
<$action-setfield $tiddler="$:/blog-startval" text={{{ [{$:/blog-startval}subtract<interval>] }}} />
PREVIOUS (Show posts from <$text text={{{ [{$:/blog-startval}subtract<interval>] }}}/> to <$text text={{{ [{$:/blog-startval}subtract[1]] }}}/>)
</$button>
</$list>
<$list filter="[{$:/blog-startval}compare:number:lt<blogcount>]">
@@float:right;<$button>
<$action-setfield $tiddler="$:/blog-startval" text={{{ [{$:/blog-startval}add<interval>] }}} />
NEXT (Show posts from <$text text={{{ [{$:/blog-startval}add<interval>] }}}/> to <$text text={{{ [{$:/blog-startval}add<interval>add<interval>subtract[1]] }}})/>
</$button>@@
</$list>

<$button>
<$action-setfield $tiddler="$:/blog-startval" text="1" />
RESET to TOP (of sort order)
</$button>

</$let>
<hr>
[[$:/blog-startval]] is currently set to: {{$:/blog-startval}}

ADDENDUM with apologies: When the $:/blog-startval field is still empty — as it would be prior to clicking either button — this setup currently ends up omitting the first result (since the “butfirst” filter step then omits the first 1, given that it finds no value at the field). So, further tweaking would be needed. I’m not able to revise at the moment, but hope that the basic approach is coming clearer.

@TW_Tones - You’re always so helpful and I want to say thank you for that, regardless of the outcome.

To answer your question, I envision the Previous | Next links at the bottom of the Blog page. To be honest, it doesn’t bother me if they appear as shown in this paragraph above (positioned left, centered or right) or if they are separated so that Previous is on the left side of the storyview and Next is on the right.

@Springer - I put the code into the Blog page, but it didn’t work well. I feel as though I should be importing a plugin for this. Is that correct? I couldn’t find anything for startval (except a website that deals with sliders).

I have saved a copy of my test site and will fiddle with it a bit more to see if I can work it out. NB: I’m technically challenged with this type of stuff. I try hard, but don’t understand what I’m doing in all honesty.

Edited to add: I managed to get something to happen. The code recognised the next 10 tiddlers but listed the linked titles at the bottom of the Blog page. Here’s an image:

Is it possible to have it load a new page with the tiddlers expanded? If not, I’d accept if the entire list (meaning all the tiddlers tagged Blog) are listed in this way on the next page. That would be better than not being able to access them at all.

Hello @TheScribe ,

My apologies. Being someone who also is a novice — relative to super-skilled people here — I can identify with being a bit disoriented at the beginning!

I try to put some time in, helping with questions that I think are somewhat within my scope. But certainly the bit of code I developed was more a proof-of-concept than something ready to drop into your site!

And I’m not a plugin developer, though others here might be interested in developing a plugin based on this idea.

At any rate, the version below should work on your site, and show the actual posts rather than just the titles. The buttons have the list conditions around them so that they’ll show only when appropriate (not offering previous when you’re only at the beginning, not offering “next” when you’re at the end of your set of posts).

[code deleted, since it’s superceded by later post]

I do hope other folks will step in, since I’m off to work!

It won’t, I’m afraid.

It was one my first attempts to give back to the community, and it has a fairly narrow range. It’s designed to let you navigate back and forth between a list of tiddlers that share a common tag. That’s it.

This sounds like an interesting challenge, and if I find time I’ll fiddle with it too

Hello again! I think I have a working solution that you can drag and drop. You will surely want to tinker with the aesthetics. But the function is more or less solid.

NOTE: This version needs TiddlyWiki v5.3.x because it uses the new <thisTiddler> variable to make the code simpler for setting its own field values. (If you don’t have such a recent version, I’d encourage you to upgrade, or reach out for follow-up…)

Just visit this demo link, and DRAG the tiddler there to your own site (and confirm the import). (Don’t worry — it won’t drag over the content of the dummy blog posts — just the frame for holding a set of posts, with navigation among the sets. I made ChatGPT generate a set of dummy blog posts about itself, but once the tiddler is on your site, it should simply display whatever is tagged “Blog” there.)

This version fixes the earlier “butfirst” glitch, and puts both the variables into fields of the same “blog frame” tiddler. This means that the solution is now “self-contained” in a way that the prior one was not. (It used a system tiddler to hold the startval).

I have the interval field set to 5, so that the demo has enough to scroll through (I didn’t generate very many dummy posts). Set the interval however you like!

I’ll also paste the code below, in its current form (to make this thread not useless beyond the half-life of my demo blog). Note dragging the actual tiddler has the benefit of including the interval and startval fields, so if you copy the code below, you would want to add those fields manually.

<$let topic="Blog" blogcount={{{ [tag<topic>!sort[created]count[]] }}} interval={{{ [<thisTiddler>get[interval]] }}}>

<div style="text-align:center;"> 
<$list filter="[<thisTiddler>get[startval]compare:number:gt[0]]">
<$button><$action-setfield $tiddler=<<thisTiddler>> $field=startval startval="0" />
RESET to TOP</$button>
</$list></div>
<$list filter="[<thisTiddler>get[startval]compare:number:gt[0]]">
<$button><$action-setfield $tiddler=<<thisTiddler>> $field=startval startval={{{ [<thisTiddler>get[startval]subtract<interval>] }}} />
PREVIOUS (Show posts from <$text text={{{ [<thisTiddler>get[startval]subtract<interval>add[1]] }}}/> to <$text text={{{ [<thisTiddler>get[startval]] }}}/>)
</$button></$list>
<$list filter="[<thisTiddler>get[startval]add<interval>compare:number:lt<blogcount>]">
@@float:right;<$button><$action-setfield $tiddler=<<thisTiddler>> $field=startval startval={{{ [<thisTiddler>get[startval]add<interval>] }}} />
NEXT (Show posts from <$text text={{{ [<thisTiddler>get[startval]add<interval>add[1]] }}}/> to <$text text={{{ [<thisTiddler>get[startval]add<interval>add<interval>] }}}/>)
</$button>@@</$list>

@@clear:both;<br>@@
<hr>

<div style="text-align:center;"> 
//Items tagged __<<topic>>__ from <$text text={{{ [<thisTiddler>get[startval]add[1]] }}}/> to <$text text={{{ [<thisTiddler>get[startval]add<interval>] }}}/> (of <<blogcount>> total)://</div>

<$let startval={{{ [<thisTiddler>get[startval]] }}}>

<$list filter="[tag<topic>!sort[created]butfirst<startval>limit<interval>]">
  <div class="blog">
  <h2><$link/></h2>
  <p style="font-weight: bold; font-style: italics;"><$view field="created" format="date" template="DD MMM YYYY hh:0mm" /></p>
<$transclude mode="block"/>
  </div>
</$list>

</$let></$let>
2 Likes

You may also be interested — at some point — in checking out this solution, which is related:

@TheScribe it may be helpful to modify the title of this topic to indicate it is not simply next/previous but “Next/previous N items in a list” or group of items etc…

  • As a result of this title I spent some time polishing a next previous button solution that proved to be somewhat off topic here. Although I will eventually share it. If you change the title I can delete this reply.

I used my editorial privileges to add clarification to title. Obviously, @TheScribe can further edit or revoke my edit.

Recently, I’ve noticed so many posts whose titles don’t quite put their themes in focus. It’s especially hard for relative novices to recognize which differences make a difference, though!

I tried this, and it resulted in a reasonable demo.

To use it, download pagination.json (1.6 KB) and drag it to your wiki.

Then create a tiddler with the fields items-per-page and page-number, and in the body, call the macro pagination passing it a filter describing the blog posts you would like to include.

It might look like this:

title: My Blog
items-per-page: 5
page-number: 1

<<paginate "[tag[Blog]!sort[created]]" >>

And that’s it!

On the demo page are a list of Potential improvements I could see making to this, but it’s reasonably functional as is.

3 Likes

Thank you @Springer and @Scott_Sauyet for the suggestions. I’ve tried them both, and got both of them to work well. Neither was difficult to use or change to suit my needs.

On this occassion, I’ve decided that the pagination.json worked exactly how I envisioned. I’m super happy with the result and I’m another step closer to finishing my website.

1 Like

Hi, I tried your Wizard Nav plugin, very well made.
I was wondering if there was a way to “combine” the two creations, it might be interesting:


Something like a pagination that always has items-per-page: 1 where you can navigate not only with previous and next but you can also navigate by selecting the desired tiddler in a tag-pill (like you can in the Wizard Nav)
But with the advantage that you can transclude the tiddler instead of opening it (as happens in Wizard Nav)

Or to put it in other words, a Wizard Nav where you don’t navigate in the storyview, but within the same “container” tiddler using transclusions


(I said items-per-page: 1 because I wouldn’t know if this thing is possible if the number is higher.)

Just a thought.

Anyway, excellent creations, congratulations! :balloon:

I can see why we might want to consider that.

But I would be very afraid of making a Frankenstein’s monster if we actually tried. I certainly wouldn’t try to build on either one of them to create the other; they’re too logically far apart. If we were to try this, I would expect it to start from scratch.

Wizard Nav Pagination
Invocation Tagging convention Explicit macro/procedure call
Target tiddlers All tiddlers sharing a common tag, where that tag itself is tagged Wizard The result of an arbitrary filter
Body handling N/A - standard TW handling The body is generated by pagination script An enhancement might use a supplied macro/procedure instead
Footer An (overridable) ViewTemplate generates the footer The footer is encoded in the pagination script

But a common pagination/navigation control would make a lot of sense. I would love to see something that could be extracted to be used by both of these. I don’t have a real sense, though, of what its interface would be like.

Good points, thanks for the reply.
I’ll think about it, if I have ideas/any files to share, I will :+1:t2:

  • It seems if we can build or enhance how we select a position in a list may be a first step.

It is my view that as a community we are quite good at building point solutions in a plugin or package and driving low level changes in the code.

  • However, we are not so good at developing shared community solutions, or de facto standards higher up in the “application” stack. Perhaps a discussion for another day. My hunch is it needs to start with a supportive infrastructure.

Until we can find away to enhance collaboration in the community, the challenge of bringing two solutions together may be best served either making a third combined solution, or by breaking both into separate modules with as many as practical being common.

Note: I maintain a “watching brief” on such subjects and continue to investigate the handling of set/lists, their navigation, reuse and combinations.

  • I will now take the idea of such navigation as being able to set a position in a list/set such that other navigation and pagination tools can access it.

We might also need useful ways to deal with a list of lists. I think it should already be possible, but it’s not at all obvious.

I’m not sure that it’s more than tangentially related, but since we already have the nth / zth operators for cases where you want, e.g., the third title in a list, it occurred to me yesterday that I would expect a title in a list to know its current position in that list. Clearly this information is already available, since list widgets can define a counter variable, but there’s no easy way to access that counter within the list filter itself. a b c +[nth[3]] will give me c, but there’s no simple way to derive 2 from b and 3 from c in the same filter.

I eventually discovered that Evan Balster had written a custom addposition operator back in 2016 (!) which did everything I needed at the time, but it’s a pity that it never made it into the core. Or, perhaps, a <counter> variable that gets defined within the context of a subfilter or a :filter/:map run, as <currentTiddler> is redefined to refer to each input string?