rubyjekylljekyll-extensions

I need my Jekyll generator plugin to run after another, but the other wants last priority


I have a custom Jekyll plugin — specifically, a generator — that I need to run after another plugin, jekyll-titles-from-headings. However, the other plugin has a generator that specifies that it is of :lowest (i.e. latest running) priority.

The temporary solution I have thrown together also specifies :lowest priority and just so happens to run after jekyll-titles-from-headings, but for reasons that I cannot discern. What I want is to have a declaration in my own generator class that guarantees my plugin after this other generator.

In my own generator class, I have tried overriding the comparison operators that appear to control plugin ordering to (in a hacky manner) hardcode a comparison result of -1 for my class. That had no effect. I tried specifying a custom @priority value of -200 (since it appears that :lowest = -100). That didn't compile.

How can I guarantee that my generator always runs after this one other generator plugin? If there were some way to specify it as a post-requisite to the other generator, that would be ideal.


Solution

  • It's an absolute hack, but you can override the spaceship method for a plugin with the following:

    class Generator < Jekyll::Generator
      ...
    
      # Override the Jekyll::Plugin spaceship to push our plugin to the very end
      def self.<=>(*)
        1
      end
    
      ...
    end
    

    Jekyll runs a .sort() on the plugins which normally pulls the priorities, but by overriding the spaceship your plugin will always sort itself last (unless another plugin does the same, in which case you're back to an unstable sort for last).

    Much like using !important in CSS, it's pretty ugly and should be avoided, but it works.

    For a less global hack, you could write the spaceship method to specifically check which plugin it is sorting against and perform the above behaviour only if it is sorting against jekyll-titles-from-headings, which effectively provides the post-requisite behaviour without potentially clashing with another plugin.