Open polux opened 4 years ago
That's a cool idea. What data structure would you propose clay should render to?
In my particular case I'm interested in getting a Map String String
that I can pass to miso's style attribute. But to make it generic enough that it's usable with other libs, I'd say any json-like structure that represents the AST of the CSS. Does that make sense?
Yep, that makes a lot of sense. You mean https://hackage.haskell.org/package/miso-0.21.2.0/docs/Miso-Html.html#v:style_, right?
Clay itself basically collects a list of Rule
s (see http://hackage.haskell.org/package/clay-0.13.1/docs/Clay-Stylesheet.html#t:Rule). If you can write a function Rule -> Map String String
, then you're halfway done.
I'm not sure this should be part of the clay
package, or rather a separate clay-miso
package. Either way I'm fine with adding such code to this github repo, even if it's a separate package.
But to make it generic enough that it's usable with other libs
That can be a long-term goal, but let's first solve the immediate problem and connect clay to miso. The next step can be refactoring and connecting to other frameworks.
Yep, that makes a lot of sense. You mean https://hackage.haskell.org/package/miso-0.21.2.0/docs/Miso-Html.html#v:style_, right?
Yes!
Clay itself basically collects a list of
Rule
s (see http://hackage.haskell.org/package/clay-0.13.1/docs/Clay-Stylesheet.html#t:Rule). If you can write a functionRule -> Map String String
, then you're halfway done.
Exactly, I had looked for that in the code of clay but it seems that such an intermediate map doesn't exist: the list of rules is converted to a Builder immediately.
I'm not sure this should be part of the
clay
package, or rather a separateclay-miso
package. Either way I'm fine with adding such code to this github repo, even if it's a separate package.
That would be definitely simpler at first. But don't you think a function of type Rule -> Map String String
would make sense in the clay package itself? Another thing I wasn't sure about is that I suppose that some rules don't make sense for an inline style (like keyframes, I don't think you can define them inline?). So that function in clay-miso
would have to be partial.
Clay itself basically collects a list of
Rule
s (see http://hackage.haskell.org/package/clay-0.13.1/docs/Clay-Stylesheet.html#t:Rule). If you can write a functionRule -> Map String String
, then you're halfway done.Exactly, I had looked for that in the code of clay but it seems that such an intermediate map doesn't exist: the list of rules is converted to a Builder immediately.
No, this map doesn't exist yet, someone needs to implement it. Maybe you? :D
I'm not sure this should be part of the
clay
package, or rather a separateclay-miso
package. Either way I'm fine with adding such code to this github repo, even if it's a separate package.That would be definitely simpler at first. But don't you think a function of type
Rule -> Map String String
would make sense in the clay package itself?
It would make more sense if the resulting map is used in some way, but I can't see how the map is sufficient information to recover the whole well-readable rendering that clay produces. clay outputs human-readable CSS, but such a map is too much of a machine format, I think.
But let's start with a small step first, and implement the function. As you suggest, let's add it to Clay.Render
. If we notice feature creep, we can still move it to a separate package.
Another thing I wasn't sure about is that I suppose that some rules don't make sense for an inline style (like keyframes, I don't think you can define them inline?). So that function in
clay-miso
would have to be partial.
Hmm, I think that's best done as a separate endofunction either on Rule
oder Map String String
that deletes all inapplicable rules. I wouldn't include that at first, but you're welcome to open a separate follow-up issue then.
Hmm, I think that's best done as a separate endofunction either on Rule oder Map String String that deletes all inapplicable rules. I wouldn't include that at first, but you're welcome to open a separate follow-up issue then.
Actually I don't think we can do without it: other than Property
I'm not sure how to translate other constructors of Rule
into entries of a Map String String
.
Actually, the low-level constructors for attributes are public in Miso, so I guess I could define my own style attribute that takes a Text
rendered by clay. It is probably way simpler than re-factoring clay's rendering to output a map.
My bad, haddock makes it look like the low-level constructors are exposed but they aren't.
@polux FWIW Here is a hacky way to integration Miso and Clay that I came up with a while back, it worked well enough for a medium-sized project with lots of client-side stuff:
-- | Put 'Clay.Css' into a Miso-compatible style property.
--
-- Allows us to use any amount of CSS written with Clay inlined in HTML or
-- dynamically as JavaScript object properties. The implementation is a bit
-- hacky, but works.
css :: Clay.Css -> Attribute action
css = Miso.style_ . Map.fromList . f . Clay.renderWith Clay.htmlInline []
where
f :: L.Text -> [(MisoString, MisoString)]
f t =
L.splitOn ";" t
<&> L.splitOn ":"
<&> \(x : y) -> (toMisoString x, toMisoString $ L.intercalate ":" y)
It would be great if in addition to rendering to text, clay could also "render" to something more structured. That way it could be used as a DSL for inline CSS in combination with libraries like miso for instance.