Trouble with hooks for a custom backlink generator

So I’ve continued tinkering with this, and decided to change a bunch of things…

I had configured pages and posts as collections in my _config.yml, like so:

# Collections
collections_dir: collections
collections:
  posts:
    permalink: /:year/:month/:day/:title/
  pages:
    output: true
    permalink: /:title/

I’ve done this for years with Jekyll sites I have built, but I started wondering if maybe I was causing some sort of hook collision with the Jekyll defaults site.posts and site.pages. So I got rid of the collections and just reconfigured my permalinks with defaults instead, like so:

# Defaults
defaults:
  - scope:
      path: ''
      type: pages
    values:
      permalink: /:title/
  - scope:
      path: ''
      type: posts
    values:
      permalink: /:year/:month/:day/:title/

Then, I needed to change how I called pages and posts in the plugin. I was originally calling them as collections, like so:

all_posts = site.collections['posts'].docs
all_pages = site.collections['pages'].docs

So I changed these two lines to:

all_posts = site.posts.docs
all_pages = site.pages

At this point, I started getting errors on jekyll build. For some reason, jekyll no longer liked this part of the plugin:

def note_id_from_note(note)
      note.data['title'].bytes.join
end

It would throw this error:

/site/_plugins/bidirectional_links_generator.rb:47:in `note_id_from_note': undefined method `bytes' for 404:Integer (NoMethodError)

page.data['title'].bytes.join\r
                   ^^^^^^

I tried a whole bunch of tweaks with no luck, mostly just generated other related errors. So I went back to the drawing board and tried to start the plugin from scratch. I also searched around for other solutions, and found this thread from 2021: Mention other pages linking to current page. The OP was also trying to get Maxime’s plugin to work, just for backlinks. TerminalAddict did a bit of a refactor of the plugin and made it much more compact, removing a bunch of the extra functionality necessary for Maxime’s template but not required to generate backlinks. I copied this approach and produced the following:

class BidirectionalLinksGenerator < Jekyll::Generator
  def generate(site)

      Jekyll::Hooks.register :pages, :post_convert do |page|
        all_posts = site.posts.docs
        all_pages = site.pages

        all_docs = all_posts + all_pages

        all_docs.each do |current_note|
          notes_linking_to_current_note = all_docs.filter do |e|
            e.content.include?(current_note.url)
          end
          current_note.data['backlinks'] = notes_linking_to_current_note
        end
      end

    end

  end

And it almost works… It does generate backlinks, but so far only for pages. Since I’m no longer using collections, I can no longer use the documents hook point, like above in this thread:

Jekyll::Hooks.register :documents, :post_convert do |docs|

If I use the pages hook point, I can get some* backlinks:

Jekyll::Hooks.register :pages, :post_convert do |page|

But if change this to use the posts hookpoint, like so:

Jekyll::Hooks.register :posts, :post_convert do |post|

I have not been able to get a backlink to a test post to work so far, whether hard-coded in HTML or generated from a Liquid loop.

I have tried combining these, like the example provided by @george-gca above, like so:

Jekyll::Hooks.register([:posts, :pages], :post_convert) do |page|

Page backlinks will continue to work with this syntax, but the do |page| needs to be modified to do both |page| and |post|, but I can’t figure out the syntax for this…

Now, even more confusingly, the some* note above… Unlike the iterations of the plugin posted above, where some Liquid loops would not generate any backlinks, while others would consistently generate a backlink for each listed link, now all Liquid loops ony my site are generating some backlinks, but not consistently generating a backlink for each listed link. The plugin seems to be skipping iterations through the for loop at random, and I have no idea why. So I find myself at another wall :confused: