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

Override a context field with nothing #913

Closed
kirelagin opened this issue Dec 18, 2021 · 5 comments
Closed

Override a context field with nothing #913

kirelagin opened this issue Dec 18, 2021 · 5 comments
Labels

Comments

@kirelagin
Copy link

(Unfortunately, I did not find an easy way to play around with contexts in a repl, so instead of showing the code, I’ll have to describe the issue using words.)

After reading the documentation for field, I was under an impression that using empty or noResult will allow me to “unset” a field in a context, but apparently it does nothing at all.

Suppose, I want to create a context that will be the same as defaultContext, but without any title field (i.e. $if(title)$ in template should not get triggered). So, naturally, I tried field "title" (const empty) <> defaultContext, but it did not work as expected – I still got a title.

This has another, in my opinion, very unexpected implication: boolField "title" (something) <> defaultContext overrides the title field with True only if the value is True, but if it is False, the value is not overridden at all and remains a (True-valued) string.

@Minoru
Copy link
Collaborator

Minoru commented Jan 6, 2022

Hi, sorry for such a late reply!

I don't see a way to short-circuit <> i.e. make it abort immediately without looking at the rest of the contexts. I mean, we could add a new CompilerErrors to indicate that the result is empty, or we could wrap all results in Maybe, but both approaches look ugly to me (although perhaps I didn't think deep enough). What I'd suggest instead is this (untested) wrapper:

withoutField :: String -> Context a -> Context a
withoutField key (Context inner) = Context $ \k a i ->
    if k == key
        then noResult $ "Field " ++ k ++ " is nullified"
        else inner k a i

You would then do this:

defaultContext `withoutField` "title"

How does that sound to you?

So, naturally, I tried field "title" (const empty) <> defaultContext, but it did not work as expected – I still got a title.

I guess you have figured out by now that empty or noResult just make the <> operator (from Semigroup) go to the next context. And that's also why boolField is the way it is. Do you have a suggestion (or a PR? :) on how we could make the doc clearer on this?

@Minoru Minoru added the feature label Jan 6, 2022
@Minoru
Copy link
Collaborator

Minoru commented Jan 29, 2022

Hey @kirelagin, did you get a chance to look at the above suggestions?

@Minoru
Copy link
Collaborator

Minoru commented Mar 11, 2022

@kirelagin, ping.

@kirelagin
Copy link
Author

Apologies for the delay. The workaround wrapper sounds pretty good to me – I can’t remember now how exactly the issue manifested for me, but, I suppose, it would work.

As for the docs, I am not exactly sure what the best way to address this would be. Maybe a note/warning could be added to the haddock of the Context newtype, If there was some sort of a Hakyll Cookbook, I would definitely add your withoutField snippet to it.

@Minoru
Copy link
Collaborator

Minoru commented Mar 23, 2022

Maybe a note/warning could be added to the haddock of the Context newtype,

Dunno. The doc already says that <> "Tries to find a key in the left context, or when that fails in the right context.". If you have a specific wording in mind, please send a pull request.

Hakyll doesn't have a cookbook, and after thinking about it a bit, I don't think I'd add this snippet to one of the existing modules either. So I'll just let it sit here for now, and if a lot of people stumble into this, I can reconsider.

@Minoru Minoru closed this as completed Mar 23, 2022
@Minoru Minoru added question and removed feature labels Mar 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants