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

Custom HSX #2009

Closed
kodeFant opened this issue Oct 25, 2024 · 4 comments
Closed

Custom HSX #2009

kodeFant opened this issue Oct 25, 2024 · 4 comments

Comments

@kodeFant
Copy link
Contributor

kodeFant commented Oct 25, 2024

Hi!

Sometimes, I would like to avoid using {...[("non-standard-attribute", "value" :: Text)]} in hsx and rather be able to extend it with my own whitelist of attributes I commonly use.

When using custom elements or js libraries with non-standard attributes, it would be nice to just have a custom HSX that just adds a whitelist.

I guess we could have it as a low level function that also hsx could use.

makeCustomHsx :: HashMap.HashMap Text TH.ExpQ -> QuasiQuoter
makeCustomHsx customAttributes = QuasiQuoter
    { quoteExp = quoteHsxExpression (HashMap.union customAttributes knownAttributes)
    , quotePat = error "quotePat: not defined"
    , quoteDec = error "quoteDec: not defined"
    , quoteType = error "quoteType: not defined"
    }

-- The standard QuasiQuoter uses the standard attributes
hsx :: QuasiQuoter
hsx = makeCustomHsx HashMap.empty

And with something like this, one can enjoy compile-time type-safety with custom attributes:

module Application.Helper.CustomHSX (customHsx) where

import IHP.HSX.QQ (makeCustomHsx)
import qualified Text.Blaze.Html5.Attributes as Attributes
import qualified Data.HashMap.Strict as HashMap

customAttributes :: HashMap.HashMap Text TH.ExpQ
customAttributes = HashMap.fromList
    [ ("tooltip", [| Attributes.customAttribute "tooltip" |])
    , ("magic", [| Attributes.customAttribute "magic" |])
    -- Add your custom attributes here
    ]

customHsx :: QuasiQuoter
customHsx = makeCustomHsx customAttributes

And then we could do this:

-- Using standard HSX (unchanged)
normal = [hsx|
    <div class="normal">content</div>
|]

-- Using custom HSX with additional attributes
custom = [customHsx|
    <custom-element 
        class="normal"      -- Standard attribute still works
        tooltip="help"      -- Custom attribute
        magic="sparkle"     -- Custom attribute
    >
        content
    </custom-element>
|]

I haven't actually tested it, so it's just pseudo for now.

If interesting, I could attempt a pull request.

@mpscholten
Copy link
Member

I like the idea 👍

one alternative could also be adding an [uncheckedHsx||] quasi quoter. Like hsx but without any checking of the attributes or tag names.

Your approach feels more in line with type safety, so likely we should go with makeCustomHsx :)

@kodeFant
Copy link
Contributor Author

kodeFant commented Oct 26, 2024

Great! If it doesn't prove to be extremely difficult, I could try to add uncheckedHsx too. Would be nice for shipping XML for example if you don't want to declare every allowed tag and attribute

@mpscholten
Copy link
Member

Great, let's try that 👍

@kodeFant
Copy link
Contributor Author

The custom thing was far too complex for me to deal with right now, so I went with uncheckedHsx #2010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants