Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get links to all calendar/tag pages #374

Open
aardvarkk opened this issue Aug 20, 2019 · 5 comments
Open

How to get links to all calendar/tag pages #374

aardvarkk opened this issue Aug 20, 2019 · 5 comments

Comments

@aardvarkk
Copy link

aardvarkk commented Aug 20, 2019

Expected behaviour

  • I'd like to display links to all other pages on the calendar/tag pages within a given calendar/tag page.

Actual behaviour

  • I'm only able to obtain prev_page and next_page links, and can't figure out a clean interface by which to obtain links to all of the other pages.

Additional information

  • Ruby version: 2.3.8
  • Middleman version: 4.3.4
  • Middleman Blog version: 4.0.3
  • OS version: macOS 10.14.5
@tdreyno
Copy link
Member

tdreyno commented Aug 20, 2019

Looks like you are right, that data for the full set is never captured or shared with templates:

It kind of happens here:
https://github.com/middleman/middleman-blog/blob/master/lib/middleman-blog/paginator.rb#L51-L64

Where would it make sense to share that data? Along side prev_page and next_page variables? I can refactor things to make that possible.

@aardvarkk
Copy link
Author

aardvarkk commented Aug 20, 2019

I started to look into making a variable called page_list that would just contain an array of all of the resources. I did find exactly that section of the code that you linked to and that's where I started making changes.

What I managed to do instead was to hack together a helper that would keep wandering through prev_page and next_page until there were none left. So I would keep accessing current_resource.locals['prev_page'] and building up an array as I walked through. It was pretty hacky but it worked without me needing to change any code in middleman-blog.

If this is a pretty fringe request I don't mind if you close it off given that there is a workaround -- it just took me quite a while to try to figure out how I could get a list of all the pages and I felt like other people might also want to do that.

@tdreyno
Copy link
Member

tdreyno commented Aug 20, 2019

That's clever. Can you put your solution code here for future folks searching for this?

@aardvarkk
Copy link
Author

aardvarkk commented Aug 20, 2019

Yep -- I should be able to post something tonight. I'll edit this comment with the general idea.

EDIT: Here's the code I promised. It's fairly specific to my perhaps-strange use case, but could probably be extended for other needs. I wanted only one blog article per page, but wanted to list all of the other pages for the given tag/calendar page on each page. That way, you could navigate the tags and calendar pages without losing the context of being interested in a certain calendar range or tag.

Here's the custom helper I made with some helper functions:

module CustomHelpers
  # Add an article as a Hash to the collection
  # I store the title for use as eventual link text and the path for the href
  # I pass the operation to do (either `unshift` or `push` 
  # to either prepend or append to the collection
  def add_article(operation_sym, article, collection, path = nil)
    collection.send(operation_sym, {
      title: article.title,
      path: path
    })
  end

  # Walk from a current resource to the next-oldest
  # The "next page" links to the *previous* article,
  # because articles are sorted descending chronologically
  # The key here is grabbing the next page with `current_resource.locals['next_page']`, then setting
  # that as the next "current_resource" for the recursive call
  def walk_older(current_resource, current_article, articles, collection)
    if prev_article = articles.find { |a| a.date < current_article.date }
      add_article(:push, prev_article, collection, '/' + current_resource.locals['next_page'].path)
      walk_older(current_resource.locals['next_page'], prev_article, articles, collection)
    end
  end

  # Same as above, but walking to newer articles/pages
  def walk_newer(current_resource, current_article, articles, collection)
    if next_article = articles.reverse.find { |a| a.date > current_article.date }
      add_article(:unshift, next_article, collection, '/' + current_resource.locals['prev_page'].path)
      walk_newer(current_resource.locals['prev_page'], next_article, articles, collection)
    end
  end
end

Here's how I use it in the template:

          <% newer = [] %>
          <% walk_newer(current_resource, current_article, articles, newer) %>
          <% older = [] %>
          <% walk_older(current_resource, current_article, articles, older) %>

          <% newer.each do |article| %>
            <li><%= link_to article[:title], article[:path] %></li>
          <% end %>

          <li><%= current_article.title %></li>

          <% older.each do |article| %>
            <li><%= link_to article[:title], article[:path] %></li>
          <% end %>

@github-actions github-actions bot added the Stale label Apr 11, 2024
@markets
Copy link
Member

markets commented Apr 15, 2024

ℹ️ This issue is stale because it has been open for more than 90 days with no activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot removed the Stale label Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants