How to render a custom attribute of <h:outputLink>?
Asked Answered
F

1

2

I am trying to implement pinterest's pinit button using a snippet like the one below:

<h:outputLink value="http://pinterest.com/pin/create/button/" class="pin-it-button" count-layout="horizontal">
   <f:param name="url" value="#{beanOne.someMethod}/sometext{prettyContext.requestURL.toURL()}"/>
   <f:param name="media" value="#{beanOne.someOtherMethod}/sometext/somemoretext/#{beanTwo.someMethodTwo}-some-text.jpg"/>
   <f:param name="description" value="#{beanTwo.someOtherMethodTwo}"/>
   <img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" />
</h:outputLink>

Here are the gotcha's:

  • the whole markup is created from the combination of four different methods from two different beans as well as some static text
  • the url parameters obviously need to be urlencoded, therefore I am using f:param inside h:outputLink so that they get urlencoded
  • the generated a tag needs to have the non-standard count-layout="horizontal" attribute

Now my question is either one of:

  • How can I inject the count-layout attribute into h:outputLink or the generated anchor tag
  • Otherwise if I cannot, what would be another non-invasive (I don't want to change the bean methods) way to accomplish the required pinit button markup?

The required markup can be found at http://pinterest.com/about/goodies/ down in the "pin it button for websites" section.

Fiske answered 22/5, 2012 at 11:24 Comment(0)
P
6

Either use a normal <a> element along with a custom EL function which delegates to URLEncoder#encode().

<c:set var="url" value="#{beanOne.someMethod}/sometext#{prettyContext.requestURL.toURL()}"/>
<c:set var="media" value="#{beanOne.someOtherMethod}/sometext/somemoretext/#{beanTwo.someMethodTwo}-some-text.jpg"/>
<c:set var="description" value="#{beanTwo.someOtherMethodTwo}"/>

<a href="http://pinterest.com/pin/create/button/?url=#{utils:encodeURL(url)}&amp;media=#{utils:encodeURL(media)}&amp;description=#{utils:encodeURL(description)}" class="pin-it-button" count-layout="horizontal">
   <img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" />
</a>

(note that the class attribute was invalid for <h:outputLink>, you should be using styleClass)

Or create a custom renderer for <h:outputLink> which adds support for count-layout attribute. Assuming that you're using Mojarra, simplest would be to extend its OutputLinkRenderer:

public class ExtendedLinkRenderer extends OutputLinkRenderer {

    @Override
    protected void writeCommonLinkAttributes(ResponseWriter writer, UIComponent component) throws IOException {
        super.writeCommonLinkAttributes(writer, component);
        writer.writeAttribute("count-layout", component.getAttributes().get("count-layout"), null);
    }

}

To get it to run, register it as follows in faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.Link</renderer-type>
        <renderer-class>com.example.ExtendedLinkRenderer</renderer-class>
    </renderer>
</render-kit>
Parasite answered 22/5, 2012 at 13:39 Comment(2)
the custom renderer looks like a much cleaner way and allows space for future requirements. thank you very much.Fiske
You're welcome. Note that you're this way JSF implementation dependent. If you ever switch to MyFaces, you'd have to change this. You could also create an independent renderer instead, but that would require lot of non-DRY boilerplate code.Parasite

© 2022 - 2024 — McMap. All rights reserved.