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

Support for websites located in subdirectories #142

Open
kalhauge opened this issue Apr 6, 2020 · 5 comments
Open

Support for websites located in subdirectories #142

kalhauge opened this issue Apr 6, 2020 · 5 comments
Labels
API documentation Improvements or additions to documentation

Comments

@kalhauge
Copy link

kalhauge commented Apr 6, 2020

Currently rib expect that the destination path will be in the root of the domain.

My website might be located at "domain.com/my-site", but rib expect everything
to be in "domain.com". This is quite common for university websites.

It would be nice if a sub-folder prefix could be automatically added. Something like:

rib generate --domain /my-site
@srid
Copy link
Owner

srid commented Apr 6, 2020

I don't understand the issue. Are you talking about Rib.routeUrl returning /foo.html instead of /my-site/foo.html?

@kalhauge
Copy link
Author

kalhauge commented Apr 6, 2020

Sorry that I was not able to describe it better. Yes, that is the problem.
Let me explain some simple solutions, and why I think they are sub-optimal:

  1. One solution would be to hard-code it everywhere:

    a_ [ href_ $ "/my-site" <> Rib.routeUrl r ] "This Internal Link" 

    However, this would break the "serve" mode.

  2. Another solution is to add "/my-site" as part of the IsRoute definition:

    routeFile = \case
      Route_Index -> return [relfile|/my-site/index.html|]

    However, if you want to serve this website in multiple places this would not work.

A better (IMHO) solution would be to be able to specify the subfolder on the command line `generate --domain /my-site".
I think that Hackyll does something similar.

My current solution is to read from the environment:

main :: IO ()
main = do 
  subdir <- maybe (pure [absdir|/|]) parseAbsDir 
      =<< lookupEnv "SUBDIR"
  Rib.run [reldir|content|] [reldir|dest|] (generateSite subdir)

The subdir can be used to describe a lref_ function, which is intended
to be a local reference, or a route reference:

lref_ :: Path Rel Path -> Route a -> Attribute
lref_ subdir r = 
  href_ . Text.pack 
  . Path.toFilePath 
  $ subdir </> fromMaybe (error "unexpected") (Rib.routeFile r)

Now this can be used in html generation. The example from before:

a_ [ lref_ subdir r ] "The Internal Link"

This solves two things. It makes route refences more typesafe, and
it can be configured to add arbitrary prefixes to the links.

Note: Ideally a RibConfig or RouteConfig would probably be a better
input to the lref_ function.

@srid
Copy link
Owner

srid commented Apr 6, 2020

Gotcha. I got confused by words like 'directory', 'subdir', etc. (filesystem notions), but the request is basically to customize the route URL (filesystem paths remain the same).

What you are asking for, IIUC, is a custom "base URL" (whose default value is "/").

Let's say we extend routeUrl to create a:

-- | The absolute URL to this route (relative to the given site root)
routeUrlFrom :: IsRoute r => Text -> r a -> Text
routeUrlFrom baseUrl r = baseUrl </> routeUrl' Relative r

Then you can use it as:

a_ [href_ $ routeUrlFrom baseUrl r] ...

Now the question becomes how to pass this baseUrl to the render function. Normally I have a Config struct and pass that around.

All that's left at this point is to take this value from the CLI. Here's where I think different to your proposal. Instead of encoding this concept in rib generate, you could do it in your own CLI handler:

# Everything before "rib" is from user code; everything after "rib" is from rib's CLI parser
$ mysite --base-url=/foo/ rib generate ...

See here for an example of how this can be done.

With this approach, the only change we would need to make to rib is to add a routeUrlFrom function.

How does that sound?

@kalhauge
Copy link
Author

kalhauge commented Apr 7, 2020

Ah.. baseUrl. Sometimes I just look the right words.

I think that would be a great solution.

Three comments:

  1. Is the reason to use Text in routeUrlFrom is to allow for non-absolute paths like "domain.com/my-site", or would it be better to use Path Abs Dir instead?

  2. While I love the small size of rib, and I think that decisions like keeping CLI as simple as possible, might be one of the reasons its so accessible, I do think there are some argument for a global config of rib. This could contain baseUrl, whether to publish drafts, and so on.

  3. Using a type-safe route-reference like lref_ have really cleaned up my code. Maybe adding something like this to the library could be beneficial.

@kalhauge kalhauge mentioned this issue Apr 7, 2020
@srid
Copy link
Owner

srid commented Apr 7, 2020

  1. I suppose if you are going to be prepending it to the result of routeFile it would indeed make sense to take a Path Rel Dir (not Abs, because path2Url takes a rel path) instead. (And then refactor the function routeUrl' accordingly). So, routeFile (default) vs fmap (myCustomRootDir </>) routeFile.

  2. Stuff like drafts, blogging features, rss feed so and so forth should probably belong to Rib.Extra. I think the core of rib should stay small. As for baseUrl, or any case where it is not clear yet, the approach I normally take is to implement that feature in the user code first, and then see how things can be generalized for re-use (among multiple sites) before adding it to rib. I see that you did something to that effect in Add runConfig #143.

  3. With the same approach, I'd like to see what the final user code looks like. Then maybe we can extract some general patterns.

In the beginning of the project, rib used to have unnecessarily sophisticated design, like using type classes (where none was needed); so these days I'm cautious of adding any general patterns. Personally I would implement whatever functionality in at least two of my sites before attempting to extract the general pattern into rib.

By the way, there is also the Zulip discussion channel for Rib.

@srid srid added the API label Apr 7, 2020
@srid srid added this to the 0.10 milestone Apr 7, 2020
@srid srid added the documentation Improvements or additions to documentation label Apr 8, 2020
@srid srid removed this from the 0.10 milestone Jul 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants