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

Toggle the presence of an attribute using Option<T> #58

Closed
lambda-fairy opened this issue Nov 7, 2016 · 4 comments
Closed

Toggle the presence of an attribute using Option<T> #58

lambda-fairy opened this issue Nov 7, 2016 · 4 comments

Comments

@lambda-fairy
Copy link
Owner

Alternative 1

let surprise = Some("Boo!");
html! {
    p title?=(surprise) "Hover over me"
}

Alternative 2

Like Alternative 1, but with the syntax title=?(surprise) instead.

Alternative 3

Use the same syntax as normal splices, title=(surprise), but use trait magic to omit the attribute when surprise.is_none().

Implementation: Add a method, fn is_present(&self) -> bool, to the Render trait. This method returns true for all types except Option<T>, which returns self.is_some(). Then at run time, the code will call surprise.is_present() to decide whether or not to emit the attribute.

Not sure how this composes -- what does title={ "I say: " (surprise) } mean?

@lambda-fairy
Copy link
Owner Author

After filing #59, I came up with another alternative: p title=(surprise)?.

@lambda-fairy
Copy link
Owner Author

lambda-fairy commented Nov 17, 2016

Looking at this again, I'm not sure what use case I have for this feature. It seems too complicated at the moment. So I'm closing it for now.

If you have a use for this, feel free to make a comment!

@Korvox
Copy link

Korvox commented Oct 31, 2017

I ran into something that could use this. I have a dataset I want to prefill a form with, but the sourcing of that data isn't uniform or guaranteed so it is all optional. If I could write it like this:

html! {
   input type="text" value?=(data.value);
}

It would be much more ergonomic than how I have it written now which looks like this:

html! {
    input type="text" value=@if let Some(val) = data.value { (val) };
}

It would also be nice because right now there is no way (I think?) to have an attribute that either exists with a value or doesn't exist with no value without doing conditionals on the entire attribute.

I thought the following form might be better but it seems attributes in conditions don't work:

html! {
    input type="text" @if let Some(val) = data.value { value=(val) };
}

@lambda-fairy
Copy link
Owner Author

lambda-fairy commented Nov 8, 2017

@Korvox you can make that shorter with a wrapper struct:

struct Optional<T>(Option<T>);

impl<T: Render> Render for Optional<T> {
    fn render_to(&self, buffer: &mut String) {
        if let Some(ref value) = self.0 {
            value.render_to(buffer);
        }
    }
}

Does that address your use case?


By the way: there's no difference between an empty value and a missing one as far as I can tell.

The only case I know of where a missing and empty attribute have different meanings is the alt attribute. An empty alt says that the image has no meaning, but a missing alt says that the image has an unknown meaning.

I haven't looked very hard though, so there might be others I've missed.

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

No branches or pull requests

2 participants