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

Option to add trailing slash to void elements #15

Open
christophhagen opened this issue Jul 13, 2024 · 2 comments
Open

Option to add trailing slash to void elements #15

christophhagen opened this issue Jul 13, 2024 · 2 comments

Comments

@christophhagen
Copy link

First off, thanks for starting this library. I'm currently experimenting with it to generate HTML pages with swift, and ran across an issue:

I created a custom path element to write inline svg:

public typealias path = HTMLVoidElement<HTMLTag.path>

public extension HTMLTag {

    enum path: HTMLTrait.Unpaired, HTMLTrait.RenderedInline { public static let name = "path" }
}

public extension HTMLAttribute where Tag == HTMLTag.path {

    static func fill(_ value: String) -> HTMLAttribute<HTMLTag.path> {
        .init(name: "fill", value: value)
    }

    static func d(_ value: String) -> HTMLAttribute<HTMLTag.path> {
        .init(name: "d", value: value)
    }
}

I can then write simple svg content:

svg(.id("some")) {
    path(.fill("currentColor"), .d("..."))
    path(.fill("currentColor"), .d("..."))
}

Once I render this, it produces the following HTML:

<svg id="some">
    <path fill="currentColor" d="...">
    <path fill="currentColor" d="...">
</svg>

I think this is valid HTML, but if I try to display the svg in Safari, it doesn't render correctly.
Apparently Safari needs a trailing slash for path, like so:

<svg id="some">
    <path fill="currentColor" d="..." />
    <path fill="currentColor" d="..." />
</svg>

Is there a way to force certain void elements to add a trailing slash when rendering? Or should I use a different approach?

I guess the alternative would be to use HTMLTrait.Paired instead of HTMLTrait.Unpaired, but that would make the HTML less compact.

@sliemeobn
Copy link
Owner

Hi, thanks for engaging!

That is the exact reason I did not include SVG stuff yet, because it behaves differently in subtle ways. HTML "prefers" no trailing slash for unpaired tags, but XML-like things like SVG require them....

So I wasn't sure if adding svg into the regular some HTML system is a good idea, or rather have a completely separate SVGBuilder approach. Also, the global namespace is littered enough as it is already by importing Elementary in a file, adding all the svg tags as well feels a bit much to me - especially since they can only be used within very narrow constraints.

In my projects, I just include things like

HTMLRaw("svg \(withParameters) goes here")

but that's obviously not the nicest.

Pro tip, for better (static) svg caching I use this trick actually (loads the actual svg from a cache-controlled file)

struct MyLogo: HTML {
    var size: Int = 60
    var basePath: String

    var content: some HTML {
        HTMLRaw("""
        <svg width="\(self.size)" height="\(self.size)" class="fill-green-500">
            <use xlink:href="\(self.basePath)/my-logo.svg#logo"></use>
        </svg>
        """)
    }
}

To summarize, I don't yet see a great way forward, but I am leaning towards having a completely separate SVG module.

@christophhagen
Copy link
Author

Okay, good to know. I'll use HTMLTrait.Paired for now, until I find the time to work on a better system for me.

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