Pages vs Posts and URL schemes

Hi all,

I’m just trying to migrate my personal blog from Nikola to Jekyll - and I’m trying to keep most of the URL scheme the same.

I’m using the jekyll-theme-chirpy theme, and in _config.yml, I have the following defaults set:

defaults:
  - scope:
      path: "" # An empty string here means all files in the project
      type: posts
    values:
      layout: post
      comments: true # Enable comments in posts.
      toc: true # Display TOC column in posts.
      permalink: /:year/:month/:day/:title/
  - scope:
      path: "_pages"
    values:
      layout: page
      permalink: /:title/
  - scope:
      path: _drafts
    values:
      comments: false
  - scope:
      path: ""
      type: tabs # see `site.collections`
    values:
      layout: post
      permalink: /:title/
  - scope:
      path: assets/js/dist
    values:
      swcache: true

I’m putting normal posts in the _posts directory, and pages in the _pages directory.

When this site builds, the pages all seem to go into a directory called /:title/ - ie it looks like for whatever reason, the templating doesn’t seem to apply.

The build process also complains about /_site/:title/index.html conflicting.

Anyone got any hints on why I’m seeing this, and how to fix it?

what happens if you remove the scope for pages?

I get the following errors when trying to run the site:

          Conflict: The following destination is shared by multiple files.
                    The written file may end up with unexpected contents.
                    /home/netwiz/git/www.crc.id.au/_site/:title/index.html
                     - _pages/2020-04-17-cyberpower-ols1000e-fan-replacements.markdown
                     - _pages/2021-06-10-backups-and-filesystem-deduplication.markdown
                     - index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html
                     - :title/index.html

I’ve been putting pages in the _pages directory… Do I need to update / set that somewhere to match a type: pages? That’s why I set a path: "_pages" - as otherwise I’m not sure how I’d include those as pages…

With the path: "_pages" in the scope, only the pages conflict:

         Conflict: The following destination is shared by multiple files.
                    The written file may end up with unexpected contents.
                    /home/netwiz/git/www.crc.id.au/_site/:title/index.html
                     - _pages/2020-04-17-cyberpower-ols1000e-fan-replacements.markdown
                     - _pages/2021-06-10-backups-and-filesystem-deduplication.markdown

normally jekyll ignores folder that have an underscore in them - did you specify in the config to include the _pages directory?

have you set pages as a collection by chance (don’t)?

I’m fairly sure what you are specifying as the permalinks is the default pretty format other than it doesn’t contain categories - maybe strip all the permalinks from the defaults and just add permalink: pretty in the config and see what happens.

I’d also try deleting the whole defaults section (or commenting it out) just to get back to where it works and then add stuff back one piece at a time to see what works.

I see what you mean… I added permalink: /:title/ to the main part of the config, then changed the defaults block to:

defaults:
  - scope:
      path: "_posts"
      type: posts
    values:
      layout: post
      comments: true # Enable comments in posts.
      toc: true # Display TOC column in posts.
      permalink: /:year/:month/:day/:title/
  - scope:
      path: _drafts
    values:
      comments: false
  - scope:
      path: ""
      type: tabs # see `site.collections`
    values:
      layout: post
      permalink: /:title/
  - scope:
      path: assets/js/dist
    values:
      swcache: true

This seems to work from a permalink standpoint, but this leaves me with the pages going under _site/_pages/:title/ - when I need them to be at _site/:title/

Maybe I’m misunderstanding, but shouldn’t using the permalink option move them into _site/:title/ (but templated) directory, and not a subdirectory like _site/_pages/.... ? or because _pages is included, it scopes as a relative path?

I think my main bit of confusion is understanding how the paths are resolved to be able to manipulate them as needed…

I don’t know - it is a good question. Your using the pages in a _pages folder is a little different and maybe is a use case that isn’t quite covered - normally pages are just scattered around and not in a specific directory.

What if you add the pages as a collection?

I’d also make a normal page not in the pages directory just to see if that does what you think it should.

I kinda think the directory being part of the path is good, that is what I expect if I make a file in /services/cool-service.html I expect the services to be in the path no matter what, otherwise the directories would all be ignored and it wouldn’t really be possible to make complex layouts with just a permalink structure?

Yeah - I’d like to keep things somewhat sane and tidy instead of just scattering pages everywhere :smiley:

For example, on disk, the files in _posts are actually sorted as _posts/2023/<files> for example, but the permalink structure fixes this to not matter.

I can fix this by specifying a specific permalink in the actual markdown file itself - which does work - but this seems like the wrong way to approach things.

I think the real issue seems to be that setting a permalink structure in defaults: seems to not get templated - ie it uses a literal value instead of expanding it to a value. Hence the files actually end up in _site/:title/ on disk - not an expanded value as you’d expect.

posts and maybe collections get more love than just pages I think. For instance it is more clear that you wouldn’t want the _posts folder to be part of the path for posts - but for pages to me it is more likely you would want whatever full path to show.

is that for pages only or are you seeing that on posts too? posts I think should work.

It only seems to be for pages.

In summary:

  1. permalink in the markdown file as words, works fine.
  2. permalink in the markdown as a template, doesn’t work.
  3. permalink in the scope for _pages, doesn’t work

This is my current itteration of config - so there’s no overlapping scopes:

defaults:
  - scope:
      path: "_posts"
    values:
      layout: post
      comments: true
      toc: true
      permalink: /:year/:month/:day/:title/
  - scope:
      path: "_pages"
    values:
      layout: page
      comments: true
      toc: true
      permalink: /:title/
  - scope:
      path: _drafts
    values:
      comments: false
  - scope:
      path: ""
      type: tabs # see `site.collections`
    values:
      layout: post
      permalink: /:title/
  - scope:
      path: assets/js/dist
    values:
      swcache: true

It still ends up on disk as the literal string _site/:title/index.html

It’s just like the template engine doesn’t get run on the permalink value - ie the scope applies fine.

If I remove the permalink: /:title/, then the pages end up as _site/_pages/2021-06-10-backups-and-filesystem-deduplication.html

If I set a global option (outside of the defaults block) of permalink: /:title/, then the file ends up at _site/_pages/2021-06-10-backups-and-filesystem-deduplication/index.html - which is funny because even that isn’t the title :smiley:

Ohhhhhhhh - I think I’ve figured it out…

image

There IS no :title available for pages. As such, I can only really use :basename - which I guess is fine as that’ll achieve the same thing as what I want just by calling the file the correct thing.

1 Like