`Source` type - Rib

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Joel McCracken

So because of the interlinking stuff I am doing, I was about to start on the specific interface for querying it. What I was thinking was that the function should be e.g. lookupLinkTarget :: TargetSpec -> MySite -> Destination

Joel McCracken

so, I was about to buid a type for MySite

Joel McCracken

what I was thinking of was something like:

Joel McCracken

data MySite = MySite LinkTargetData [Source XmlM]

Joel McCracken

HOWEVER, i notice that Source not only contains the "source" information but also target

Joel McCracken

which is semantically a bit separate IMO

Joel McCracken

(maybe I might want to have a source that has no direct desintation?)

Joel McCracken

just something I noticed, I will pobably end up using something besides Source for now

Sridhar Ratnakumar

I have metadata files that I read with "readSource". Then fmap it over "sourceVal" to get just the value (discarding other fields). Would this not be better? So, "MySite LinkTargetData [XmlM]"

Sridhar Ratnakumar

Actually no need for fmap,as readSource returns the underlying type directly

Sridhar Ratnakumar

https://github.com/srid/website/blob/master/src/Main.hs#L63

Source for my website. Contribute to srid/website development by creating an account on GitHub.
Joel McCracken

well the only thing is i'd like to also have the actual source filename as well

Joel McCracken

I suppose though that too could be optional

Sridhar Ratnakumar

If you can show me how your Source2 type would look in code (in the context of your project), I can evaluate it better.

Sridhar Ratnakumar

(I gtg soon; but feel free to put it here or on Github issue)

Joel McCracken

Na I think what you have is fine. I was mostly trying to say that it surprised me to see the dest filepath in the source data. But

Joel McCracken

I can get around it fine

Joel McCracken

and I can just ignore it too :)

Sridhar Ratnakumar

Still interested in looking at what your code looks like, so let me know when it is done, I'll take a look at your repo.

Sridhar Ratnakumar

In the early days I used a tuple (FilePath, repr). Eg: ("/foo/bar.md", <MMark doc>).

Sridhar Ratnakumar

And then some function that converted /foo/bar.md to /foo/bar.html for using in the HTML rendering step.

Sridhar Ratnakumar

I figured why not put it in a ADT, and provide a simple sourceUrl function that gives the url to the rendered source. But it sounds like this URL in your case is something else ....

Sridhar Ratnakumar

I'm writing an IRC log viewer using rib. And hit the abstracation ceiling of Source. Specifically I want to determine the output file name from the parsed structure (which contains the channel name).

Sridhar Ratnakumar

It is basically impossible to customize buildHtml locally, because the Source constructor is not exported. Definitely a design smell that needs to be simplified, in the same manner as how I got rid of type classes.

Sridhar Ratnakumar

https://github.com/srid/rib/pull/94

Background: I'm writing an IRC log viewer using rib. And hit the abstracation ceiling of Source. Specifically I want to determine the output file name from the parsed structure (which contains ...
Sridhar Ratnakumar

I'm looking into the possibility of removing the Source type entirely

Sridhar Ratnakumar

Minimum info we need is the parsed type, and the URL to it.

Sridhar Ratnakumar

I think this URL is best constructed and defined manually by the user.

Sridhar Ratnakumar

Actually .. removing Source makes the user code rather verbose and ugly. For now, think I'll keep it.

Sridhar Ratnakumar

Source type is now entirely gone, replaced by a Route-based mechanism which looks pretty cleaner to me. See https://github.com/srid/rib-sample/commit/5a7f0c6d16efbd24065655b204c5ca11797439e6#diff-f8f3412da88cd4806f23d59fe59ebc3bR33

Sample site for the Rib static site generator. Contribute to srid/rib-sample development by creating an account on GitHub.
Sridhar Ratnakumar

The function hook thingy (i.e. readSource) is gone as well. No more needless passing-function-to-function indirections. Just call your parser directly in Action monad. (example in that link)

Joel McCracken

I ended up making my own sort-of source type

Joel McCracken

that is just a tuple of like

Joel McCracken

Then there is a second type called ProcessedSource which includes the output destination

Joel McCracken

this solved the weirness

Joel McCracken

i like the new disign; basically it separates the process into:

  1. read the sources
  2. process the sources/prepare for rendering
  3. render the sources
Sridhar Ratnakumar

Joel McCracken said:

(Path, XmlDoc)

This is isomorphic to Rib.Route's (r a, a) basically, FWIW.

Joel McCracken

i'm still tyring to figure out if i want to use the route

Joel McCracken

for now its easier to just not

Sridhar Ratnakumar

that's a sensible approach. you can use it when you need it. i designed Rib.Route after figuring out based on my various static sites.

Sridhar Ratnakumar

Joel McCracken said:

Then there is a second type called ProcessedSource which includes the output destination

Also, this is why there is a IsRoute type class, to provide a routeFile (which routeUrl uses) that tells the output destination for a given route.

Joel McCracken

I think it should work though

Sridhar Ratnakumar

Joel McCracken said:

i like the new disign; basically it separates the process into:

  1. read the sources
  2. process the sources/prepare for rendering
  3. render the sources

Yes, you can get away with your own Shake action, and use only two functions from Rib: forEvery (for step 1), and writeFileCached (after step 3)

Joel McCracken

thats exactly what I am doing

Sridhar Ratnakumar

and forEvery is basically a 3-line function that wraps Shake's forP

Joel McCracken

I implemented it so my pjosts write to entries/<post-name>/index.html FYI

Joel McCracken

oh thats what I was unsure about

Joel McCracken

it seemed like I couldn't easaily separate where I am acrtually writing a file to with the URL I use for links

Joel McCracken

so what i mean is that i'd like to have my links look like entries/fp-glossary which would require the file to actally be written to entries/fp-glossary/index.html

Joel McCracken

looks like you explicitly programmed for that?

Sridhar Ratnakumar

I do that "index.html" trick when implementing IsRoute instance for my Route, and routeUrl automatically strips the "index.html" because it is redundant for URLs.

Joel McCracken

what i mean is that if I have my file written to entries/fp-glossary/index.html, then the generated link will be entries/fp-glossary

Joel McCracken

ill probably factor to it then when I'm done fixing a few things

Sridhar Ratnakumar

If you plan on using Route, you can start with a very basic implementation that has only one route:

class Route a where
  Route_Whatever :: Path Rel File -> Route XmlDoc

instance IsRoute Route where
  routeFile = \case
    Route_Whatever fp -> dropExtension fp </> [relfile|index.html|] -- something like this
Sridhar Ratnakumar

And in future if you want to support non-xml docs, you can add another constructor, eg: Route_NewStuff :: Path Rel File -> Route Pandoc

Sridhar Ratnakumar

Working code for that index.html trick with Routes here: https://github.com/open-editions/open-editions.org/blob/930888f/Main.hs#L54-L69

Open Editions website and infrastructure. Contribute to open-editions/open-editions.org development by creating an account on GitHub.
Sridhar Ratnakumar

Then, (Route_Whatever fp, xmlDocForFp) will be isomorphic to your (Path, XmlDoc) type, and the second type ProcessedSource becomes redundant! Because you can just use the former, and call routeFile on it to get the HTML file path.

Sridhar Ratnakumar

... with the added benefit of being able to use routeUrl on that value