I'm trying to use mixins in Yesod's Lucius, but have run into a problem. Currently my 'center' mixin is the only one that seems to work, which also happens to be the only mixin without variable interpolation, although I'm not sure that is related to the problem the problem.
Lucius:
@keyframes blink {
0% {opacity: 0}
40% {opacity: 0.8}
80% {opacity: 0}
100% {opacity: 0}
}
@-webkit-keyframes blink {
0% {opacity: 0}
40% {opacity: 0.8}
80% {opacity: 0}
100% {opacity: 0}
}
html, body {
height: 100%;
margin: 0;
}
*, *:after, *:before {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
^{box-sizing "inherit"}
}
header {
min-height: 100%;
z-index: 0;
background-image: url(@{StaticR images_landing__jpg});
background-position: center center;
background-size: cover;
.greeting {
min-width: 30%;
padding: 3%;
background-image: url(@{StaticR images_neg_lines_png});
background-repeat: repeat;
text-align: center;
^{center "both"}
color: whitesmoke;
h2, h4 {
font-family: "Lato";
font-weight: 300;
}
h4 {
font-family: "Lato";
^{font-size 20}
}
h1 {
font-family: "Tangerine";
font-weight: bold;
color: #ffffff;
^{font-size 96}
}
}
.scroll-link {
^{center "x"}
bottom: 5%;
.scroll-arrow {
display: inline;
path {
stroke: white;
fill: transparent;
stroke-width: 1px;
animation: blink 2s infinite;
-webkit-animation: blink 2s infinite;
}
path.a1 {
animation-delay: -1s;
-webkit-animation-delay: -1s;
}
path.a2 {
animation-delay: -0.5s;
-webkit-animation-delay: -0.5s;
}
path.a3 {
animation-delay: 0s;
-webkit-animation-delay: 0s;
}
}
}
}
.main-container {
background: whitesmoke;
}
Mixins:
{-# LANGUAGE QuasiQuotes #-}
module Mixins
( center
, box_sizing
, font_size
, unlink
) where
import Text.Lucius
import ClassyPrelude.Yesod
center :: String -> Mixin
center axis
| axis == "x" =
[luciusMixin|
left: 50%;
-webkit-transform: translate(-50%, 0);
-ms-transform: translate(-50%, 0);
transform: translate(-50%, 0);
|]
| axis == "y" =
[luciusMixin|
top: 50%;
-webkit-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
transform: translate(0, -50%);
|]
| otherwise =
[luciusMixin|
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
|]
box_sizing :: String -> Mixin
box_sizing box_model =
[luciusMixin|
-webkit-box-sizing: #{box_model};
-moz-box-sizing: #{box_model};
box-sizing: #{box_model};
|]
font_size :: Double -> Mixin
font_size size =
[luciusMixin|
font-size: #(pxsize}px;
font-size: #(remsize)rem;
|]
where
pxsize = show size
remsize = show $ size * 0.125
unlink :: String -> Mixin
unlink color =
[luciusMixin|
color: #{color};
text-decoration: none;
|]
Error:
[...]/Foundation.hs:132:15:
Exception when trying to run compile-time code:
"
[...]
" (line 94, column 1)
unexpected end of input
expecting "/*", "}", "#", "@" or "{"
checkIfBlock
Code: widgetFile "default-layout"
In the splice: $(widgetFile "default-layout")
Things I've troubleshot:
It's quite possible I'm missing something obvious, and I'd hate to be that guy, however there's not much in the way of documentation for these types of things. Perhaps this can help someone else in a similar position.
Anyways, any and all help is appreciated.
EDIT:
As it turns out, after merging some separate lucius files, the 'unlink' mixin also compiles without error. Due to the fact that it is, structurally speaking, essentially identical to other mixins such as 'box_sizing' I now know that interpolation is not the culprit, nor the formatting of the function (Guards vs. Equation).
I'm becoming more and more suspicious of the formatting in the Lucius file as it seems the Haskell code is insignificant. I'm starting to feel the problem might just be basic css syntax error that i'm blind to for whatever reason.
EDIT 2:
I have merged the Lucius code for my navbar, which revealed that a mixin that could not previously compile, under certain (albeit unknown) circumstances, can succeed.
The relevant code:
(note the 'font_size' mixin succesfully compiles in this code)
/* Navbar */
@navheight: 6rem;
nav {
z-index: 10000;
position: absolute;
background-color: transparent;
color: rgba(255, 255, 255, 1);
height: #{navheight};
line-height: #{navheight};
^{font-size 16};
.left {
padding-left: 2rem;
padding-right: 2rem;
height: #{navheight};
.brand {
display: inline;
font-family: "Lato";
font-weight: bold;
^{unlink "inherit"};
}
.more {
display: inline;
font-family: "Lato";
}
}
.right {
height: #{navheight};
ul li {
display: inline-block;
padding-left: 2rem;
padding-right: 2rem;
a {
font-family: "RaleWay";
display: block;
text-align: center;
^{unlink "inherit"};
}
}
}
}
Well, the error was caused by a few typos (font-size -> font_size; box-sizing -> box_sizing
), sadly I had glazed over the idea of a naming error due to the fact that I was not getting a 'font-size' is not in scope
error. The parser was seeing the -
as subtraction due to the fact that they are not allowed in haskell function names. On the plus side, I now know the insides of Yesod and shakespeare very well, and can hopefully help people with actual problems.