Mention other pages linking to current page

Hi
I’ve a question how to make a thing similar as in Your first seed — My digital garden in the sidebar with title Notes mentioning this note.

Can you help me to reproduce this feature? Please :pray:

Here’s what I tried:
I am structuring the project same in the theme project and added plugin in _plugins folder. Here’s the plugin script which I believe is responsible for doing this no hope it work but it’s not working and not doing anything at. I tried tweaking this like in plugin script changing all_docs only to all_notes and changing all_notes. I found even in layout script site.collections[’“notes”].docs show nothing so I did all_notes = site.notes.

I’ve never worked with ruby so please help me how to make this thing in any way or at help me dubug Digital Garden theme script working somehow.

Note that non official gems installed or any ruby plugins added to _plugins dir will not work on GH Pages in the standard flow. Are you using GH Pages?

You can still test a plugin locally easily.

Run a jekyll build --verbose to see where your plugin is getting loaded, or not.
Use --trace if you get an error and need more info

Did you mean to link to this page?

notes_graph.html

It sounds like you meant to link to a ruby script

Or when you say plugin do you mean JavaScript code?

[OFF-TOPIC] : On the other hand, departing from the one you mention, Brennan Brown went further with his Digital Garden… .
For inspiration ?

I mean to say a ruby plugin. Please check _plugins folder in the Digital Garden theme.
I already tried your mentioned solutions. I even tried Jekyll.logger.info “Hello” but not worked.

Follow the plugins generator tutorial in the docs.

Use puts 'hello' inside a generate method.

You can run your plugin through Jekyll serve or build.

You can run it directly with ruby. This might not work fully because it needs Jekyll in the context but it can tell you of Ruby syntax errors.

bundle exec ruby _plugins/testing.rb

If you have problems getting a Hello World generator to work, then open up a new topic discussion around that and share your repo and the command you use to run Jekyll.

Any problem around the specific digital garden plugin usage is best discussed from point of a generic working plugin and can continue here.

mm interesting

looks like the magic happens here:

  {% if page.backlinks.size > 0 %}
  <div style="display: grid; grid-gap: 1em; grid-template-columns: repeat(1fr);">
  {% for backlink in page.backlinks %}
    <div class="backlink-box">
    <a class="internal-link" href="{{ backlink.url }}">{{ backlink.title }}</a><br>
    <div style="font-size: 0.9em">{{ backlink.excerpt | strip_html | truncatewords: 20 }}</div>
    </div>
  {% endfor %}
  </div>
  {% else %}

  <div style="font-size: 0.9em">
    <p>
      There are no notes linking to this note.
    </p>
  </div>
  {% endif %}

using a local _plugin

https://raw.githubusercontent.com/maximevaillancourt/digital-garden-jekyll-template/73ba1d475a32ac08f9c0a5cc881741eea4ea3fb6/_plugins/bidirectional_links_generator.rb

I’d quite like to use this too :slight_smile:

1 Like

well that was surprisingly easy !!!

in _layout/default.html

{% if page.backlinks.size > 0 %}
    <div class="backlink-box p-3 m-5 border shadow-sm d-print-none">
        <ul>
        {% for backlink in page.backlinks %}
            <li><a href="{{ site.url }}{{ backlink.url }}">{{ backlink.title }}</a></li>
        {% endfor %}
        </ul>
    </div>
{% endif %}

in my css:

.backlink-box {
    background-color: #f0f3ff;
}
.backlink-box:before {
    content: "What links here";
    font-style: italic;
}
.backlink-box li {
    line-height: 1em;
}

and finally, the magic plugin (which was surprisingly easy)

A special note here: I have a collection called “docs”
You will need to alter
all_notes = site.collections['docs'].docs
to suit your own needs (you might have a collection called “fruit”)
all_notes = site.collections['fruit'].docs

in _plugins/backlinks_generator.rb

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

    all_notes = site.collections['docs'].docs
    all_pages = site.pages
    all_docs = all_notes + all_pages

    # Identify backlinks and add them to each doc
    all_notes.each do |current_note|
      notes_linking_to_current_note = all_notes.filter do |e|
        e.content.include?(current_note.url)
      end
      current_note.data['backlinks'] = notes_linking_to_current_note
    end

  end

end

screenshot:

1 Like

I noticed a typo in my above code yesterday. The plugin only creates links for “collections”

if you want backlinks for pages and posts as well then:

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

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

    all_docs = all_notes + all_posts + all_pages 

    # Identify backlinks and add them to each doc
    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

but … somehow EVERYTHING is linked to my home page “/” so I put an exclusion into my layout

{% assign home = site.html_pages | where: 'url', '/' | first %}
 {% if page.url != home.url %}
    {% if page.backlinks.size > 0 %}
      <div class="backlink-box">
        <ul>
        {% for backlink in page.backlinks %}
          <li><a href="{{ site.url }}{{ backlink.url }}">{{ backlink.title }}</a></li>
        {% endfor %}
        </ul>
      </div>
    {% endif %}
{% endif %}
1 Like

I’m necro-threading this @TerminalAddict to see if you might have figured this out in the last four years… I’m trying to get working the same BidirectionalLinksGenerator plugin that started this thread. I’ve adapted your solution for a more compact BackLinksGenerator plugin. But both your version, and Maxime’s version, don’t consistently work for links that are generated by a Liquid for loop iterating through site.pages or site.posts.

I wrote up my latest investigation in more detail here: Trouble with hooks for a custom backlink generator - #8 by steinea.

The summary is that this is my plugin:

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

I’ve added the hook logic, because without this the plugin runs before files are converted from markdown to html, and consequently Liquid has not yet been converted, and thus links that will be generated by Liquid aren’t picked up by the plugin. The :post_convert event means the plugin now runs after files have been converted but before they’ve rendered.

Unfortunately, backlinks are only generated sporadically. I have some big lists and tables that are generated by a Liquid loop iterating through a filter, and seemingly randomly those links will get picked up by the backlink generator. It’s very strange :thinking: