Search code examples
jsffaceletspinterest

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


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.


Solution

  • 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>