Wyam2 / wyam

A modular static content and static site generator written in .NET. Fork of Wyam project.
https://wyam2.github.io/
MIT License
6 stars 1 forks source link

Blog recipe posts in root URL #2

Closed savornicesei closed 3 years ago

savornicesei commented 3 years ago

Issue by jansotola Monday Feb 03, 2020 at 17:02 GMT Originally opened as https://github.com/Wyamio/Wyam/issues/2


We're migrating our blog to WYAM. For SEO reasons we'd like to keep our posts in root URL (not in /posts/ subfolder). For example /my-article-1 instead of /posts/my-article-1.

I know we can use redirects (using metadata RedirectFrom:), but it is not enough for us. We need the final (redirected) URL to stay in root.

When setting BlogKeys.PostsPath to /, an error "Rooted globbing patterns are not supported" occurs. When setting BlogKeys.PostsPath to empty string, an error "Access to the path 'c:\index.html' is denied." occurs (because WYAM is trying to overwrite index of homepage with index of archive page).

Is there any way how to do it properly?

savornicesei commented 3 years ago

Comment by daveaglick Wednesday Feb 05, 2020 at 01:56 GMT


It’s definitely possible, a couple different approaches come to mind. One way would be to override the output path at the end of the pipeline before the file gets written. Take a look at https://github.com/Wyamio/Wyam/issues/612#issuecomment-363944693 and the follow-up comments. I think that code is still valid but I’ve been so heads down in Statiq recently (the successor to Wyam) that I might be confusing parts of the two. Let me know if you run into any trouble adapting that code.

If that doesn’t work or seems to confusing/heavyweight let me know and I’ll brainstorm some alternatives. One of the things I love about how Wyam worked out is that it’s so flexible - the downside is that’s it’s not always immediately obvious the best way to customize something since there are so many possibilities :)

savornicesei commented 3 years ago

Comment by jansotola Wednesday Feb 05, 2020 at 09:17 GMT


Thanks! It has helped. The final code is here:

Pipelines["BlogPosts"].Append(
  Meta(Keys.RelativeFilePath, (doc, ctx) =>
  {
    // just copied from the original implementation
    string fileName = doc.Bool("FrontMatterPublished")
      ? doc.FilePath(Keys.SourceFileName).ChangeExtension("html").FullPath
      : doc.FilePath(Keys.SourceFileName).ChangeExtension("html").FullPath.Substring(11);
    // put posts to the blog root (don't add any path before the filename)
    return fileName;
  }));

Now I have the following environment:

So the main problem is solved. But it would be nice to change the archive URL to archive/ while keeping the posts source still in input/posts/. I can do it by setting URL rewriting rule on my production server, but doing it directly in WYAM would be better. Can you, please, advice, where to modify the pipeline to achieve this?

savornicesei commented 3 years ago

Comment by daveaglick Saturday Feb 29, 2020 at 20:54 GMT


FYI - the original Wyam project is being moved to statiqdev to continue work there as Statiq Web (the successor to Wyam and the Wyam blog recipe). Since this issue relates specifically to Wyam, I've transfered it to a new replacement project for legacy Wyam issues.

savornicesei commented 3 years ago

Comment by jansotola Friday Apr 17, 2020 at 16:15 GMT


I've managed to do renaming of the "Archive" page web folder by rewriting BlogArchive pipeline. It may be a dirty and brute force solution but it works:


int archiveIndex = Pipelines.IndexOf("BlogArchive");
Pipelines.Remove("BlogArchive");
Pipelines.Insert(archiveIndex, "BlogArchive",
  // most of the lines have been copied from WYAM Blog.cs
  new Wyam.Web.Pipelines.ConditionalPipeline(
    ctx => ctx.Bool(BlogKeys.GenerateArchive),
    new Wyam.Web.Pipelines.Archive(
      "BlogArchive",
      new Wyam.Web.Pipelines.ArchiveSettings
      {
        Pipelines = new string[] { "BlogPosts" },
        TemplateFile = ctx => "_Archive.cshtml",
        Layout = "/_Layout.cshtml",
        PageSize = ctx => ctx.Get(BlogKeys.ArchivePageSize, int.MaxValue),
        Title = (doc, ctx) => "Archive",
        // the only redefined line
        RelativePath = (doc, ctx) => $"{ctx.DirectoryPath(BlogKeys.PostsPath, ".").FullPath.Replace(ctx.String(BlogKeys.PostsPath), "archive")}"
      })));
qqq
savornicesei commented 3 years ago

Comment by daveaglick Thursday Apr 23, 2020 at 00:25 GMT


Great, glad you found a solution!