How to create a page from a generator plugin?

Hey!

I’d like to know how to create a page from a generator.

I tried Jekyll::Page.new(site, site.source, ".", "test.html") but it raises

Error reading file /***/test.html: No such file or directory @ rb_sysopen - /***/test.html

Thanks!

I am running this locally.

Look at the error message.

It says it cannot read the filename. This happens inside read_yaml when it attempts to read frontmatter from a file.

         1: from /Users/mcurrin/repos/_static-sites/jekyll-blog-demo/vendor/bundle/ruby/2.7.0/gems/jekyll-3.9.1/lib/jekyll/convertible.rb:41:in `read_yaml'

/Users/mcurrin/repos/_static-sites/jekyll-blog-demo/vendor/bundle/ruby/2.7.0/gems/jekyll-3.9.1/lib/jekyll/convertible.rb:41:in `read': 

  No such file or directory @ rb_sysopen - /Users/mcurrin/repos/_static-sites/jekyll-blog-demo/about.html (Errno::ENOENT)

I pointed at an existing about.md file in my project. Then the code is valid, but not useful - the about page is no longer /about.html but /:path/index.html which is a peculiar path.

module SamplePlugin
  class MyPageGenerator < Jekyll::Generator
    safe true

    def generate(site)
      dir = '.'
      name = 'about.md'
      site.pages << Jekyll::Page.new(site, site.source, dir, name)
    end
  end
end

Sorry I can’t see what is the appropriate way to make a page.

Oh I got it! I got clues from the Jekyll Feed plugin, which generates a feed.xml file based on pages on the site.

It uses PageWithoutAFile so it doesn’t get the read error. See jekyll-feed source.

Here is my plugin. It generates a file my-file.xml with one row abcdef.

module SamplePlugin
  class MyPageGenerator < Jekyll::Generator
    safe true

    def generate(site)
      dir = '.'
      name = 'my-file.xml'

      site.pages << Jekyll::PageWithoutAFile.new(site, site.source, dir, name).tap do |file|
        file.content = 'abcdef'
        file.data.merge!(
          "layout"     => nil,
          "sitemap"    => false,
        )
        file.output
      end
    end
  end
end

I made layout nil so there is nothing else on the page. OR you can use a layout - the abcdef content gets inserted as {{ content }} of the layout.

To do that, replace nil above, or take out the merge and set layouts for all pages to be page in config file.

1 Like

Oooh that’s interesting, thanks a lot, I’ll try it

1 Like

It works as expected, thanks! :+1:

1 Like