antwarjs / antwar

A static site generator built with React and Webpack.
https://antwar.js.org/
MIT License
460 stars 35 forks source link

Generalize to support multiple entry points (from one blog to many) #65

Closed bebraw closed 9 years ago

bebraw commented 9 years ago

It should be possible to host multiple blogs within one site. Of course an entry point like this could be something else (gallery, whatnot).

This might need some thinking. I have a feeling our configuration will have to change to support this. I expect you would want to apply some specific styling per entry point. It might be a good idea to allow modifying that through configuration.

eldh commented 9 years ago

Haven't thought this through properly but we might also want to consider using sub-sites to solve this problem.

bebraw commented 9 years ago

It seems to me the cleanest way to solve this is to push require.context to user land. We would simply have a section like this at antwar.config.js:

  paths: {
    webpack_react: function() {
      return require.context('./manuscript', true, /^\.\/.*\.md$/);
    }
  }

Key would map to root url and value would resolve context. This will keep Webpack happy and gives you extra control over which files to include in context in case you want to use something else than Markdown (might make sense in some case perhaps).

I have a feeling this could be a good starting point for something more advanced. Note that the configuration can be optional. If it's not included, we simply skip it.

We may end up with some sort of abstraction issue with the blog draft feature (it's too specific) but we can worry about that later. Just need to get something simple to work at first.

If you are ok with the idea, I can go ahead with the implementation. It seems to me the toughest part was just figuring out how to deal with require.context.

eldh commented 9 years ago

Sounds pretty good. We should also make sure it's available for plugins to hook into.

eldh commented 9 years ago

But yeah, go ahead!

bebraw commented 9 years ago

See https://github.com/antwarjs/antwar/tree/multiple-paths. It implements the basic scheme. Note that the current version isn't backwards compatible. It shouldn't be difficult to implement backwards compatibility but I'm not sure if we really need it.

What do you think of drafts? Should I do just

  drafts: {
    webpack_react: function() {
      return require.context('./manuscript_drafts', true, /^\.\/.*\.md$/);
    }
  }

Then it would attach these to output based on matching key.

I realized it might be useful to abstract navigation a bit (now it maps based on url, not good if you want i18n) but we can get back to that later. Also dates need extra thought. In my case files simply won't have them and the data isn't relevant to my use case. Again, separate issue.

eldh commented 9 years ago

Both in the case of dates and url:s, they can be modified by plugins. I think it would be good if this could also be implemented as a plugin. I'm thinking we would have hooks for providing posts and drafts. That way we would keep existing functionality by default and open up for other ways of loading data (including multiple folders, but could be over http or db just as well).

bebraw commented 9 years ago

I started thinking... Why not to allow plugin definition per individual path? You might want to process them differently after all. If we get the abstraction right now, that will go a long way.

bebraw commented 9 years ago

We'll need to think through theming. You definitely don't want to apply same base theme for each path. This will likely require some additional mapping so you can customize theme attached to a path based on need.

In my case having the blog fields and blog theme for index doesn't make a lot sense. My content (Markdown chapters) cannot use YAML headmatter and I won't add it (breaks something else). So the system has to adapt to this. Just need to make sure there are enough hooks for customizations such as this.

Another example of this is something like an image gallery. You would just point a directory full of photos to it, apply some plugins (ie. generate thumbnails) and apply image gallery theme to it. After this you would end up with a nice index and possibly a page per photo.

eldh commented 9 years ago

Both examples are very interesting. But yeah, allowing maps of plugin arrays makes sense (to be applied per folder).

Something like:

plugins: {
  blog: [rssPlugin, prevnextPlugin],
  manuscript: [customBookLoaderPlugin],
  gallery: [imageGalleryPlugin, rssPlugin]
}

And if you send in an array it would behave the same as now (apply the same plugins to everything).

bebraw commented 9 years ago

Yeah, plugins object would work. I need to play around with this a bit more to get something nice to render. As mentioned there are some bonus challenges as I cannot rely on YAML headmatter to exist.

eldh commented 9 years ago

The YAML bit could be handled in preProcess/postProcess hooks right?

bebraw commented 9 years ago

@eldh Yeah, there needs to be something that generates some of the metadata required.

bebraw commented 9 years ago

As mentioned at Gitter I made some good progress on this. Here's a sample config. I just kept adding hooks till I had enough to make my site work. Note that these new hooks work also on site and theme level. I also sanified the internal structure of the code a bit. Easier to work with.

We probably aren't that far off dropping direct dependency on Markdown now given you can override a lot of stuff. That's a good thing in my books.

That fs bit is problematic. I think we'll need to proxy it or something to make development mode work correctly. The problem obviously is that fs doesn't exist in browser context. We could provide a little fs API of our own, inject it to configuration and use that on the browser side. In that case it would provide the cached data and everything should work.

I haven't thought about section specific plugins yet but I suppose I have to do that eventually.

bebraw commented 9 years ago

I did tons of work on this today. I think we're getting close. See commit log for exact detail. Suffice to say there's now enough infrastructure for my purposes. Though that doesn't mean I won't hit the limits anytime soon.

@eldh Can you go through the work at some point? No hurry, I know the last week of May can be interesting. Just need to understand what's missing before merging.

Section specific plugins can probably wait. They might be nice to have at some point, though.

In addition we need to go through project dependencies at some point and just start dropping the ones we don't need. This will help to keep the core light.

eldh commented 9 years ago

Awesome! I'll try to go through it later, possibly tomorrow.

bebraw commented 9 years ago

It's probably easiest to test against https://github.com/survivejs/webpack_react (master branch). Both -d and -b should work.

There was some shiftiness with relative paths (react-router uses absolute...). I wanted to support relative ones as you might not host the site at root. Most of this should be done although I realized I would have to preprocess image paths in my case. Also navigation configuration isn't as simple as I initially thought. I think Nav.coffee will require a little fix for this to work (see BlogLink, we need to rename that).

We can probably push some of the relative logic to a higher level (resolve ../.. ... there). After that it's just a matter of consuming that on components (no need to implement the logic there unlike now).

bebraw commented 9 years ago

This got done. Time to close.