Git Product home page Git Product logo

lucid's People

Contributors

9999years avatar andrewthad avatar athanclark avatar babababag avatar bergmark avatar chrisdone avatar christiantakle avatar crdueck avatar davecturner avatar dbaynard avatar enobayram avatar ggreif avatar intolerable avatar jacksonneal avatar jeffreyrosenbluth avatar jml avatar michaelxavier avatar phadej avatar ryanglscott avatar saurabhnanda avatar sjakobi avatar supki avatar teofilc avatar tfausak avatar wraithm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lucid's Issues

How to factor out Term instances?

I have the situation where I want to factor out a pattern of two elements (which bootstrap dictates):

spanElem :: Term arg result => Text -> arg -> result
spanElem = elemWithClass "span"

inputGroupBtn_ :: Term arg result => arg -> result
inputGroupBtn_ arg = 
  spanElem "input-group-btn"
    $ termWith "button" [ class_ " btn ", type_ "button" ] arg

Since termWith "foo" [] is :: arg -> result and spanElem "bar" is :: arg -> result as well, I’d expect it to work, but the following error is thrown:

ootstrap.hs:134:51: error:
     Could not deduce (Term arg arg) arising from a use of termWith
      from the context: Term arg result
        bound by the type signature for:
                   inputGroupBtn_ :: Term arg result => arg -> result
        at bootstrap.hs:133:1-50
      Possible fix:
        add (Term arg arg) to the context of
          the type signature for:
            inputGroupBtn_ :: Term arg result => arg -> result
     In the second argument of ($), namely
        termWith "button" [class_ " btn ", type_ "button"] arg
      In the expression:
        spanElem "input-group-btn"
        $ termWith "button" [class_ " btn ", type_ "button"] arg
      In an equation for inputGroupBtn_’:
          inputGroupBtn_ arg
            = spanElem "input-group-btn"
              $ termWith "button" [class_ " btn ", type_ "button"] arg

Better way to implement conditional HTML tags?

Here's what I was trying to do. Depending on whether row ^. R.clientDomain evaluated to Maybe x or Nothing include or exclude the small_ tag from the HTML output.

Here's the best that I could do, and I'm still looking for a shorter way to get this done. (Btw, this solution isn't even 100% correct. If row ^. clientDomain is Nothing this still includes an empty <small></small> tag in the HTML)

instance (ToHtml a) => ToHtml (Maybe a) where
  toHtml (Just x) = toHtml x
  toHtml Nothing = mempty

  with td_ [class_ "client-name"] $ do
    div_ (toHtml $ row ^. R.clientName)

    -- TODO: this shouldn't be there if the domain is NULL
    small_ (toHtml $ row ^. R.clientDomain)

div not nesting inside a

I have the following code that is causing some strange behavior when the actual html is generated.

a_ [href_ "polimorphic.com", style_ "display:block"] $ do div_ [class_ "...", style_ "..."] $ do ....

However when the html is generated it doesnt nest the div inside the a and instead the a tag gets propagated through the div tag in multiple spots.

It looks something like this
div_ [class_ "the containing div"] a_ [href="https://www.polimorphic.com"] div_ [style="some div"] a_ [href="https://www.polimorphic.com"] div_ [style="some other div"] a_ [href="https://www.polimorphic.com"]

Pretty Print HTML

Is there a way to turn an Html a directly into a pretty printed/shown Text?

Better way to implement conditional attributes?

I'm wondering if there is better/shorter way to get the conditional checked_ attribute:

    makeCheckbox label name value = with div_ [class_ "checkbox"] $ label_ $ do
      input_ $ [type_ "checkbox", name_ name] ++ (if value then [checked_] else [])
      (toHtml label)

Add `property` attribute

OG meta tags utilize the property attribute on meta tags, this attribute is currently not supported by Lucid, requiring the use of makeAttribute instead.

See: http://ogp.me/

Performance issues with HtmlT over IO?

I started noticing some severe performance drop when combining Scotty's ActionT with Lucid's HtmlT. A little benchmarking produced the following: https://github.com/vacationlabs/monad-transformer-benchmark which seems to suggest that the underlying problem may be with HtmlT IO a, which takes more than 2x the time required for HtmlT Reader or HtmlT Identity

benchmarking renderText
time                 32.04 ms   (31.14 ms .. 32.54 ms)
                     0.997 R²   (0.994 R² .. 1.000 R²)
mean                 31.73 ms   (31.25 ms .. 32.21 ms)
std dev              1.049 ms   (785.1 μs .. 1.321 ms)
variance introduced by outliers: 11% (moderately inflated)

benchmarking renderTextT Identity
time                 31.37 ms   (30.17 ms .. 32.47 ms)
                     0.995 R²   (0.989 R² .. 0.998 R²)
mean                 32.90 ms   (32.23 ms .. 33.53 ms)
std dev              1.359 ms   (1.064 ms .. 1.839 ms)
variance introduced by outliers: 11% (moderately inflated)

benchmarking renderTextT Reader
time                 33.45 ms   (32.94 ms .. 33.94 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 34.38 ms   (33.95 ms .. 35.18 ms)
std dev              1.177 ms   (647.7 μs .. 1.982 ms)
variance introduced by outliers: 11% (moderately inflated)

benchmarking renderTextT IO
time                 74.52 ms   (73.08 ms .. 75.69 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 75.17 ms   (74.51 ms .. 76.00 ms)
std dev              1.247 ms   (880.2 μs .. 1.742 ms)

Haskell-cafe discussion: https://mail.haskell.org/pipermail/haskell-cafe/2017-January/126141.html
Reddit discussion: https://www.reddit.com/r/haskell/comments/5qpi15/expected_performance_drop_while_using_monad/

Pretty print html

I do not see there is a way to print html in a human readable formatted fashion.

Update to HTML5.2

HTML5.2 is now a W3C Recommendation (14 December 2017), therefore it would
be good idea to update Html5 module to include things in the spec.

I suggest to add both spec, and MDN links as follows, so lucid haddocks
could act as a good summary of what's in HTML5.2:

-- | The @poster@ attribute
-- [W3C REC](https://www.w3.org/TR/html5/semantics-embedded-content.html#element-attrdef-video-poster)
-- [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attr-poster)
poster_ :: Text -> Attribute
poster_ = mkAttribute "poster

HTML5.2 Changes and
HTML5.1 Changes would
help to spot missing things. However, I'd prefer a complete spec scan anyway.

How does renderBS deal with Text inside the HtmlT monad?

If I have two versions of the following snippet:

storefrontAngularApp :: Html ()
storefrontAngularApp = div_ $ do
  script_ [type_ "text/javascript", src_ "inline.bundle.js"] ("" :: Text)

vs

storefrontAngularApp :: Html ()
storefrontAngularApp = div_ $ do
  script_ [type_ "text/javascript", src_ "inline.bundle.js"] ("" :: BSL.ByteString)

...and I call renderBS storefrontAngularApp on both of them -- it works. How is Lucid handling Text/ByteString internally? Is this going to have any perf impact? Is one preferred over the other? Is it possible at all to use hard-coded strings without having to annotate their types and letting the render* function figure out which type to use?

Possibly related to #44

ghc-8.6.1 support?

lucid-2.9.10 has a version constraint on base that prevents building with ghc-8.6.1, but when that constraint is removed the build succeeds and seemingly works fine. So I wonder why that constraint was added in revision 1 by @phadej?

xhtml ?

I have tried to use lucid for creating xhtml (html5 + xhtml ie.),
use <br/> instead of <br> eg.,

<img.../> instead of <img ...> ,
<link>...</link>

so far my approach was to introduce new tags myself:

closingLink_ :: Term arg result => arg -> result
closingLink_ = term "link"

xmlBr_ :: Monad m => [Attribute] -> HtmlT m ()
xmlBr_ = with (makeXmlElementNoEnd "br")

xmlHr_ :: Monad m => [Attribute] -> HtmlT m ()
xmlHr_ = with (makeXmlElementNoEnd "hr")

-- and then in my pages:

closingLink_ [rel_ "stylesheet",type_ "text/css",href_ "screen.css"] ""

xmlBr_ []

xmlHr_ []

I would have thought that this is a more common thing to do
(xhtml can still be used even in the age of html5, and one may
argue that it is a good thing to do so)

obviously it's kind of tiresome to introduce all these
xhtml tags by hand, would it be possible

  • to either have them predefined (next to the existing tags br_, img_):
    don't know what would be good names for them: xbr_, ximg_ maybe ?
  • or to just use the the existing tags: br_, img_ etc
    and have a different renderer take care of producing xhtml ?

Thanks in advance.

Change `class_` type

Now, the type of Lucid.Base.class_ is Text -> Attribute.
However, class attribute is used with multiple params usually.

I suggest to change the type of Lucid.Base.class_ to [Text] -> Attribute and the logic to such as:

class_ :: [Data.Text.Text] -> Attribute
class_ cs = makeAttribute "class" $ Data.Text.intercalate " " cs

"role" attribute

I see this used a lot in Bootstrap at least, so might be nice to have

role_ :: Text -> Attribute
role_ = makeAttribute "role"

since that seems to exist for most attributes.

How to emit raw HTML entities?

How do I make this work so that it emits &times; and not &amp;times;?

with button_ [class_ "close", data_ "dismiss" "modal"] $ span_ "&times;"

p with colspan property

lts 3.10

λ> renderText $ p_ [colspan_ "2"] "xD"
"<p colspan=\"2\">xD</p>"

Is there any property checking provided? Or planned?

instance ToHtml L.ByteString

I'm after toHtmlRaw for L.ByteString. If this is something that won't be added to lucid what's my best and most efficient alternative to toHtmlRaw in my application (since 'build' isn't exposed)? In my application I'm generating 100MB HTML files so memory usage is an important consideration.

Possible to derive ToHtml for newtypes on Text?

I have quite a few newtypes in my core app for greater type safety, eg:

newtype Tag = Tag T.Text deriving (Show, Eq, Ord)

For the purpose of ToHtml it would be alright to treat them at-part with Text. Is it possible to auto-derive a boilerplate ToHtml instance for such cases?

Could not deduce (Term (HtmlT m0 ()) (m a0))

Hi

I'm getting some compilation errors with ghc when using Lucid which go away when I add a type signature to the function. I can understand that in some situations ghc just can't infer the type and that's to be expected. I was just wondering if someone could explain me how I can understand these errors and more importantly how I can predict them, i.e. I would like to know that if I do x then I get the type error. For instance in one case if I had a one html tag x it would compile but if I would do sequence_ [x, x] it would not compile, which to me seems very mysterious. Also I'm completely incapable of deciphering the type error I get, so that just leaves me with adding type signatures to functions randomly until the error goes away. If someone could explain me how to deal with this errors in a consistent way I would appreciate it.

example of error:

--withPaste :: Paste -> HtmlT Identity ()
      withPaste (Paste n t _) = h1_ $ do
        h1_ $ toHtml n
        pre_ $ toHtml t

this is the error I get when I comment out the type signature:

https://gist.github.com/miguel-negrao/dd924cf34efce5afd507

full source:
https://gist.github.com/miguel-negrao/319cbe65044f3bdee392

Refactor to provide MonadHtml

I believe that having a MonadHtml analogous to MonadReader would make it possible to create neat single-purpose HTML widgets with controlled access to the application data model (without direct access to IO, for example).

Is such a large API change worth considering or would it be better to create a fork?

HTML comments

Is there any ongoing work to support embedding comments in html?

How to prevent Text from being composed with HtmlT

Yes, you read that right. Here is the context: we are trying to internationalize our application, and instead of manually verifying that there are no hard-coded strings in the HTML, we'd like the type-system to help us.

Is there any way to force HtmlT to force the programmer to use IText instead of Text, where newtype IText = IText Text and the the only way the create an IText is via I18n.t someTranslationKey

Creating <object>

It seems I can't get such HTML, because data_ is not exactly what I need:

<object data="movie.swf"
  type="application/x-shockwave-flash"></object>

Existing data_ takes two arguments and yields data-foo="bar".

Please advise :) Maybe raw HTML is an option.

Or use makeAttribute for a custom attribute?

Expose data constructor for HtmlT

I'm working with a monad transformer stack involving HtmlT that looks like this:

type M = HtmlT (StateT Int Identity)

And there's a place in my code where I'd like to be able to write a function:

seed :: Int -> M a -> Svg a

And I can't write this if I don't have access to the data constructor. One obvious solution would be to flip the ordering of the stack like so:

type M = StateT Int (HtmlT Identity)

But lucid doesn't have an mtl-style interface so I would need to call lift almost everywhere since HtmlT is the monad transformer I use way more often. (Note: I'm totally fine with the lack of an mtl-style typeclass. I don't even like using mtl to begin with.)

Identity instance for ToHtml?

What do you think about an identity instance for ToHtml?

instance a ~ () => ToHtml (HtmlT m a) where
  toHtml = id
  toHtmlRaw = id

This is useful in the scenario that you have a function that is polymorphic over anything that is ToHtml, but when you end up in the situtation that you want to call this function on data where there isn't an instance available (and defining it is impossible without orphan instances) - the only option is to have the user cast ToHtml and then having the function use the toHtml = id implementation.

mmorph instances

It would be nice to use HtmlT with exceptions' mtl-style typeclass headers. I'll try to implement it myself and submit a PR.

A toHtmlPrec might be a good idea

While brain-storming MathML for lucid, I came across operator precedence issues. There is <mfenced> for bracketing, maybe we shoud be generate that by means of a new class
ToHtmlPrec which provides a showsPrec-like mechanism for parenthesised output.
Or possibly toHtmlPrec could go into class ToHtml, even.

Lucid monad transformer memory leak?

Hi,

I submitted an issue to scotty scotty-web/scotty#193 but on my latest test it appears a "HtmlT (S.State ()) ()" also leaks GBs of memory. So far I have only been able to reproduce this when the HtmlT is 3 levels (or more) deep. Is there anything in Lucid that may cause this?

{-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
import Web.Scotty
import Web.Scotty.Internal.Types
import Lucid.Base
import Lucid.Html5
import Control.Monad
import qualified Data.ByteString.Lazy as BL
import qualified Control.Monad.State.Lazy as SL
import qualified Control.Monad.State.Strict as S
import Data.Default.Class (def)
import Data.Functor.Identity

main = do
  BL.putStr $ SL.evalState (runS $ renderBST (myhtml :: HtmlT (ScottyM) ())) def --bad
  BL.putStr $ runIdentity $ renderBST (myhtml :: HtmlT Identity ()) --good
  BL.putStr $ runIdentity $ evalHtmlT $ renderBST (myhtml :: HtmlT (HtmlT Identity) ()) --good
  BL.putStr $ S.evalState (renderBST (myhtml :: HtmlT (S.State ()) ())) () --bad

myhtml :: Monad m => HtmlT m ()
myhtml = replicateM_ 2 $ div_ $ do
           replicateM_ 1000 $ div_ $ do
             replicateM_ 10000 $ div_ "test"

edit: opps, fixed bad copy/paste

Integrate lucid-from-html

lucid-from-html converts html into the lucid DSL, but is an experimental program. Once it is stable, it may be worth integrating into lucid itself, as discussed in #16 .

If this is desirable, this issue should track requirements for that program to be merged into lucid.

Add align_

As far as I can see, align_ is not supported.

Change term indication symbol

As I see from code HTML5 terms are hard coded with postfix _ . I want to have functionality to use terms with prefix/postfix defined by user beside standard option, something like 'body or body'.
I found it less distracting, especially with big chunks of code. I think Template Haskell will be suitable for this task.

What is best option to achieve this?
Is this change to code structure useful and I should submit pull request, or just keep it in my fork?

Would it be possible to add an Term instance to Text ?

At the moment you have to use toHtml when using Text variable which is bit noisy. For example you can do

myBody = title_ "my title"

but

    myBody title = title_ title :: Text -> Html ()

doesn't work. You have to do

myBody title = title_ (toHtml title)

It perfectly makes sense, but it took me a while to understand why the first version worked but not the second. I didn't realize that Html overloaded strings and thought "my title" was a Text.

Hashable instance for Attributes

Hi Chirs,
Hope I'm not becoming a pest. I need an instance of Hashable for Attribute in
diagrams-svg, but the constructor of Attribute is not exposed. Would you mind
either exposing the constructor or providing a Hashable instance.

thanks
jeff

Doc clarification for new starters

I found the docs at https://hackage.haskell.org/package/lucid-2.9.6/docs/Lucid.html difficult (well, impossible) to follow, due to eliding some things that are probably clear to an experienced Haskeller but non-obvious otherwise. I think it's just the following 3 lines, without which the examples provided won't run in ghci:

:import Lucid
:import Data.Monoid ((<>))
:set -XOverloadedStrings

(I realise that OverloadedStrings is mentioned, but the current phrasing "is written" doesn't make it explicit that you have to do something in order for them to be written like that...)

If that kind of change is something that would be generally welcome, I'm happy to draft a PR if that'd be helpful.

Expose monadic state in ToHtml class

Hey there,

I've found myself leveraging HtmlT quite often for its monadic state - I'll encode some crazy constraints in m like MonadBaseControl IO, so I can perform application-related effects when I render a view, where the read-only state of that view is represented by a data type which implements this typeclass.

I'm wondering if the exposure of the m type variable could help with effect-stack specific rendering instances, rather than forcing a view to be pure:

toHtml :: (ToHtml a, Monad m) => a -> HtmlT m ()

would become

toHtml :: (ToHtml m a, Monad m) => a -> HtmlT m ()

and instances, originally looking like

instance ToHtml State where
  toHtml State{foo,bar} = do
    p_ "something forcibly pure, due to this html working forall m"

could become

data Env = Env
  {hostname :: String, databaseQuery :: Query -> IO [Result], ...}

type AppM = ReaderT Env IO

instance ToHtml AppM State where
  toHtml State{foo,bar} = do
    Env{hostname,databaseQuery,etc} <- lift ask
    p_ $ "The hostname: " <> T.pack hostname

Personally I think this would be a major advantage for server-side rendering, as it could model something similar to Elm or Thermite.

How to write helper functions that generate "wrapping" HTML?

I'm trying to do something like..

container_ :: Term arg result => arg -> result
container_ arg = table_ [align_ "center", class_ " container "] $ do
  tbody_ $ do
    tr_ $ do
      td_ arg

... which can be used like:

div_ $ do
  container_ $ do
    strong_ "wil this work"
  container_ [class_ "extra-classes"] $ do
    strong_ "what about this?

... but I can't get the definition of container_ to type-check. The best that I could get to compile is:

container_ :: (Monad m) => HtmlT m () -> HtmlT m ()
container_ arg = table_ [align_ "center", class_ " container "] $ do
  tbody_ $ do
    tr_ $ do
      td_ arg

"mixed" test fails on 32-bit platforms

renderText (p_ [class_ "foo", style_ "attrib"] (do { style_ ""; style_ ""})) can evaluate either to <p style="attrib" class="foo"><style></style><style></style></p> or to <p class="foo" style="attrib"><style></style><style></style></p> depending on the relative hash values of "style" and "class". The "mixed" test from testAttributes accepts only the former, but on 32-bit platforms, which use a different string hash function than 64-bit platofrms to, it gets the latter and fails. testAttributesWith has the same problem.

How to get integers in HTML?

I'm sure I'm missing something very obvious, but I'm struggling with the following:

td_ (1::Int)

<interactive>:58:1: error:
    • Non type-variable argument in the constraint: Term Int result
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall result. Term Int result => result
� :set -XFlexibleContexts
� td_ (1::Int)

<interactive>:60:1: error:
    • No instance for (Term Int a0) arising from a use of ‘it’
    • In a stmt of an interactive GHCi command: print it
� td_ (show 1::Int)

<interactive>:61:6: error:
    • Couldn't match type ‘[Char]’ with ‘Int’
      Expected type: Int
        Actual type: String
    • In the first argument of ‘td_’, namely ‘(show 1 :: Int)’
      In the expression: td_ (show 1 :: Int)
      In an equation for ‘it’: it = td_ (show 1 :: Int)
� td_ (Data.Text.pack $ show 1::Int)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.