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

Streamlining of LocalizedClaim into rendering #41

Open
chrysn opened this issue Nov 13, 2024 · 1 comment
Open

Streamlining of LocalizedClaim into rendering #41

chrysn opened this issue Nov 13, 2024 · 1 comment

Comments

@chrysn
Copy link

chrysn commented Nov 13, 2024

yew-oauth2 re-exports the openidconnect::LocalizedClaim, eg. through [yew_oauth2::context::Claims::name()].

In the context of rendering HTML as yew usually is, it should be possible to render them into HTML in some way -- ideally as just <dt>Name</dt><dd>{ claims.name().unwrap() }</dd> (or maybe <ViewLocalized claim={claims.name()}>) -- eventually, it should use the context's language to determine whether a suitable string is present, or, finding none, produce something like <span lang="next_AVAILABLE">Name in next available language</span>. (There may be some space for convenience tool for handling non-string items such as EndUserProfileUrl, but maybe that's really just something that'd either go into a link or not).

Given that yew_oauth2::context::Claims is just a pub type, solving this might need either an explicit HTML component that guides the process, or wrapping the pub-type into a newtype that then provides pre-wrapped HTML viewable items rather than the raw LocalizedClaim – but I think the former is more maintainable.

I'm just getting familiar with the latest style of yew (I was used to writing a model more explicitly, now looking into the functional style), maybe I'll come up with something to address this; early feedback on the concept would be appreciated.

[edit: Added example]

Example implementation

What I'm using right now does about half of what would make sense: It marks content with a lang attribute, but it does not consider the context of the page, and presents the first instead of the suitable label:

#[derive(PartialEq, Properties)]
// PartialEq is required to derive Properties; the fn has more requirements
pub struct LocalizedClaimProps<T: PartialEq> {
    // Rc implements ImplicitClone
    pub claim: std::rc::Rc<openidconnect::LocalizedClaim<T>>,
}

/// Use like:
/// ```
/// html!(<div>
/// if let Some(nickname) = claims.nickname() {
///     // Showing nickname name because unlike full name we can make keycloak publish
///     // them localized, eg. if we claim all our nicknames are German by setting
///     // Client scopes / profile / mappers / nickname / TokenClaim Name to
///     // "nickname#de" -- mainly this demos that ViewLocalizedClaim really does
///     // something useful.
///     <>{ " (" }<ViewLocalizedClaim<openidconnect::EndUserNickname> claim={ std::rc::Rc::new(nickname.to_owned()) } />{ ")" }</>
/// }
/// </div>)
/// ```
#[function_component(ViewLocalizedClaim)]
pub fn view_claim<T: PartialEq + core::ops::Deref<Target = String>>(props: &LocalizedClaimProps<T>) -> Html {
    let Some((lang, val)) = props.claim.iter().next() else {
        return html!();
    };
    if let Some(lang) = lang {
        html!(<span lang={ lang.as_str().to_owned() }>{ val.to_string() }</span>)
    } else {
        html!({ val.to_string() })
    }
}
@ctron
Copy link
Owner

ctron commented Nov 20, 2024

Sure, makes sense. Adding a new component would be great.

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