Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Odysseas Doumas
Scripts inside h:head are not included inside head
December 6, 2016 9:57 PM
Answer

Odysseas Doumas

Rank: New Member

Posts: 14

Join Date: June 22, 2016

Recent Posts

I am using Liferay tomcat bundle 6.2.5 and i am developing a primefaces 6.0 portlet application using maven.

As the title says, i can't include any scripts (both local and remote like gmap api) inside the head section. I also posted here. An example would be:

1    <h:head>
2        <script
3            src="https://maps.google.com/maps/api/js?key=MY_KEY"
4            type="text/javascript" />
5    </h:head>


The weird thing is that this happened after i attempted to upgrade my project to the latest faces version. When i was using these dependencies it worked as expected.
 1         <dependency>
 2            <groupId>com.liferay.faces</groupId>
 3            <artifactId>liferay-faces-bridge-impl</artifactId>
 4            <version>4.2.5-ga6</version>
 5        </dependency>
 6        <dependency>
 7            <groupId>com.liferay.faces</groupId>
 8            <artifactId>liferay-faces-portal</artifactId>
 9            <version>4.2.5-ga6</version>
10        </dependency>


I should also say that i am aware of the header-portlet-javascript portlet property, but it is not an ideal workaround for my case. I am developing several portlets that utilize the p:gmap component so i need to include the google maps api script inside all these portlets. And because it is required to use an api key that may change over time, it would be at least tedious to change the liferay-portlet.xml in several places and redeploy, but also including the script in a theme level would not be ideal as many of my portlets don't need the maps api.

By adding it the way i want, i can introduce a custom portal(company) property, create a managed bean that loads that property and just change it from the Liferay control panel whenever i want.

I also downloaded the primefaces applicant demo portlet, added the same code inside it's main view, but still no script to be found so i believe it must be a general issue/bug/feature. Any help appreciated.
David H Nebinger
RE: Scripts inside h:head are not included inside head
December 7, 2016 6:38 AM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 12933

Join Date: September 1, 2006

Recent Posts

You should never include scripts and/or css in the portlet body. Period.

Scripts and css should be included using the portlet annotation properties (for LR7) or in liferay-portlet.xml.

This is a rule. It doesn't matter if you are using JSF, PF, Faceletes or any other rendering technology. Scripts and CSS should never be in the body.
Odysseas Doumas
RE: Scripts inside h:head are not included inside head
December 7, 2016 8:07 AM
Answer

Odysseas Doumas

Rank: New Member

Posts: 14

Join Date: June 22, 2016

Recent Posts

Hello and thank you for the reply.

David H Nebinger:
You should never include scripts and/or css in the portlet body. Period.
...
This is a rule. It doesn't matter if you are using JSF, PF, Faceletes or any other rendering technology. Scripts and CSS should never be in the body.


I am kind of confused with this statement for many reasons.
  1. When you say body i presume you mean the view that defines the markup and not the actual html tag
  2. As i said in my post, this used to work before.
  3. Many times you may want to include a script (remote or not) only inside a subtotal of a portlet's views pages, which can't be done from liferay-portlet.xml. There are many examples (for jsp too) where developers put the javascript inside a view
    1(<h:outputScript .... target="head" ></h:outputScript>
    )
Kyle Joseph Stiemann
RE: Scripts inside h:head are not included inside head
December 7, 2016 1:55 PM
Answer

Kyle Joseph Stiemann

LIFERAY STAFF

Rank: Liferay Master

Posts: 552

Join Date: January 14, 2013

Recent Posts

Hi Odysseas,
This is a regression bug. I've created FACES-2974 to track my progress in fixing this. You can watch that issue to see when it's fixed.

To workaround this issue, you can create a composite component with a name attribute. The name must end in either "css" or "js" and should probably be unique per view to ensure that it is always loaded. For example, create the following resources/workaround/headElements.xhtml file:

<?xml version="1.0" encoding="UTF-8"?>
<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:cc="http://xmlns.jcp.org/jsf/composite" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/xhtml http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd">

<!-- Workaround for https://issues.liferay.com/browse/FACES-2974 -->
<cc:interface>
<cc:attribute name="name" required="true" />
</cc:interface>

<cc:implementation>
<cc:insertChildren />
</cc:implementation>

</ui:component>


To use this component with the google maps script mentioned above:

<workaround:headElements name="#{view.viewId}.js">
<script src="https://maps.google.com/maps/api/js?key=MY_KEY"
type="text/javascript" /></script>
</workaround:headElements>

--------------------------------------------------------------------------------------------


As an aside, I will respectfully disagree with David's statement that you "...should never include scripts and/or css in the portlet body." For JSF, it's actually better to add resources via outputScript and outputStylesheet (and plain old script, style, and link when FACES-2974 is fixed) since it's the standard JSF mechanism for adding resources, and Liferay Faces will remove duplicate resources that Liferay cannot (since Liferay Faces understands the name and library convention of JSF resources).
David H Nebinger
RE: Scripts inside h:head are not included inside head
December 7, 2016 1:49 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 12933

Join Date: September 1, 2006

Recent Posts

Yes, Neil beat me up about this too. I just have a hard time conceding the point emoticon

Note for any JSP or other view tech folks, this does not mean you too can embed the script tags right in your html fragments. The JSF bridge specifically handles these tags correctly; other view techs won't.

If you're not in the JSF bridge camp, then stick to the guideline I posted.
Odysseas Doumas
RE: Scripts inside h:head are not included inside head
December 7, 2016 2:01 PM
Answer

Odysseas Doumas

Rank: New Member

Posts: 14

Join Date: June 22, 2016

Recent Posts

Thank you both for your assistance and feedback. And David thanks for the useful advice, always welcomed by a newbie in web application programming like me. Best wishes to the Liferay and Faces team.
Kyle Joseph Stiemann
RE: Scripts inside h:head are not included inside head
December 7, 2016 2:03 PM
Answer

Kyle Joseph Stiemann

LIFERAY STAFF

Rank: Liferay Master

Posts: 552

Join Date: January 14, 2013

Recent Posts

Glad I could help. Please let us know if that workaround works. Thanks for using Liferay Faces!

- Kyle