Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blog recipe posts in root URL #2

Closed
jansotola opened this issue Feb 3, 2020 · 5 comments
Closed

Blog recipe posts in root URL #2

jansotola opened this issue Feb 3, 2020 · 5 comments

Comments

@jansotola
Copy link

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?

@daveaglick
Copy link
Member

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 :)

@jansotola
Copy link
Author

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:

  • posts source code is in input/posts/ folder as usual
  • posts pages are generated to output/ folder
    and they are accessible on root URL (e.g. http://localhost:5080/)
  • index.html of archive page is generated to output/posts/ folder
    and the archive page is available on posts/ URL (e.g. http://localhost:5080/posts/)

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?

@daveaglick
Copy link
Member

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.

@daveaglick daveaglick transferred this issue from statiqdev/Statiq.Web Feb 29, 2020
@jansotola
Copy link
Author

jansotola commented Apr 17, 2020

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

@daveaglick
Copy link
Member

Great, glad you found a solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants