Liferay 7.2 - use journalarticle class in custom jsp hook - liferay

I have a module PortalHook that contains :
my class XCustomJspBag implements CustomJspBag
my jsp file terms_of_use (custom_jsps/html/portal/terms_of_use.jsp)
I need to use the JournalArticle class in this jsp file but when I add the following import :
<%# page import="com.liferay.journal.model.JournalArticle" %>
It always get me an error :
Une erreur s'est produite à la ligne: [245] dans le fichier Java
généré:
[C:\x\bundles\tomcat-9.0.17\work\Catalina\localhost\ROOT\org\apache\jsp\html\portal\terms_005fof_005fuse_jsp.java]
Only a type can be imported. com.liferay.journal.model.JournalArticle
resolves to a package
Right now i'm stuck here.
(I've imported com.liferay.journal.pai-4.5.2.jar in the pom.xml)

Looking at the CustomJspBag interface, it looks like it's only revealing the name of JSPs contained in a given module. I read this as them being resolved as relatively simple strings, and not processed within your custom module at all.
The problem is that you're injecting JSPs into Liferay's core, and you want the JSP to be dependent on a module. By definition that's something that shouldn't be done statically, but can be created dynamically, through explicit runtime means.
One option that comes to my mind is to try a Dynamic Include (DI) in your custom JSP. While the documentation talks about existing dynamic includes in JSPs, you can totally make up your own, and insert them into your custom JSPs. Then implement a proper DI with the new key that you came up with. As far as I remember, DIs will be resolved and executed within their module's context, so you'd have all of your dependencies there.
My expectation is that you can implement your DI in the same bundle that also holds your custom JSP.
Another alternative is to use any other kind of runtime dispatches, but I think that they're resulting in more work than DIs (provided they work the way I assume they do)

Related

Upgrade LanguageUtil.get method

Good afternoon, I am new to liferay and I am trying to migrate the code of a portlet from 6.2 to 7.4, I need to know how to use the LanguageUtil.get() method in liferay 7.x, currently it is implemented like this in my JSP LanguageUtil.get(pageContext, "key"), but I get an error "PortletConfig get/format methods" I have tried some ways like LanguageUtil.get(themeDisplay.getLocale(), "key") but I can't get the error to go away, any suggestion or correct way is appreciated to do it.
In a JSP you'd often use <liferay-ui:message key="key"/>, to prevent too many code snippets in the JSP. With this, you'd have no upgrade efforts.
If you want to use LanguageUtil, with a specific ResourceBundle (e.g. the one that comes with the module that you're upgrading), you'll need the locale as well: ResourceBundleUtil.getBundle(locale, this.getClass().getClassLoader()) - you can get the relevant locale through pageContext or themeDisplay. Then use LanguageUtil.get(resourceBundle, key)

How to put catche in liferay?

Earlier we are putting catche in liferay with help of below code.
MultiVMKeyPoolUtil.put("SCHOOL", "ID", "Files");
In Liferay 6.2 MultiVMKeyPoolUtil not available so how can we put catche.
There are no method like put in MultiVMPoolUtil class. I had search many alternative but couldn't find put method in it.
As MultiVMKeyPoolUtil not supported by liferay 6.2. I had used MultiVMPoolUtil class like below.
MultiVMPoolUtil.getCache("SCHOOL").put("ID","Files");
If you want to put collection as cache use below code.We require to make list serializable
MultiVMPoolUtil.getCache("SCHOOL").put("ID",(Serializable) courses);

Two JSF libraries providing the same renderer

Short Version:
If two JSF library jar files both include a custom renderer for the same family and type, is there any way from within the library itself (i.e. not from the containing app) of specifying which one should be used? Something like assigning a priority, with higher ones used in preference to lower ones?
Longer Version:
I'm using Primefaces in a project and trying to override the provided head renderer with my own:
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Head</renderer-type>
<renderer-class>com.example.MyHeadRenderer</renderer-class>
</renderer>
</render-kit>
If I put that into the WEB-INF/faces-config.xml of the war file then it's all good, and my renderer gets used.
However, if I try to deploy my code as part of a library jar (my-utils.jar), with the renderer defined in META-INF/faces-config.xml, then the Primefaces one is used. This contains exactly the same definition, so I'm guessing it just depends on the order they get loaded. Indeed, renaming my library to "xx-comps.jar" works, so it would appear that JSF is loading faces-config.xml files from all jar files in alphabetical order, with later entries just overwriting earlier ones.
Is there any way of forcing the selection to my library?
So far, I have these options:
Put my renderer directly into the WEB-INF/faces-config.xml of the war.
Build a custom Primefaces jar with that one renderer definition
removed.
Rename my library and rely on some (undocumented as far as I can
see) behaviour from the JSF loader.
Add a custom renderkit which extends the standard one, and reference
that from my war WEB-INF/faces-config.xml.
The first three all work but are not ideal, as (1) and (2) require changes outside my library, and (3) just looks dodgy as hell....
The fourth is just an idea as I've never written a render kit before so not aware of the effort involved. No idea if it is practical or would work, but it is better than (1) because at least the application only references a single render kit, and does not need to be updated if/when new renderers are added. Happy to put more effort into researching this approach if it seems a reasonable solution.
Also, I'd ideally prefer to use annotations rather than XML:
#FacesRenderer(componentFamily = "javax.faces.Output", rendererType = "javax.faces.Head")
public class MyHeadRenderer extends Renderer {
...
}
Thanks
You can specify the ordering via <ordering> in faces-config.xml of the JAR.
E.g. if you want your utility library to be loaded after all others, then just do so:
<ordering>
<after>
<others />
</after>
</ordering>
If you want to force an explicit ordering, then hook on specifically PrimeFaces, which has a <name>primefaces</name> in its faces-config.xml:
<ordering>
<after>
<name>primefaces</name>
</after>
</ordering>

Rendering a layout template inside a Liferay portlet

I'm trying to render a layout template with nested portlets inside my custom Liferay portlet. Liferay's own "Nested Portlets" portlet does it using the RuntimePortletUtil in view.jsp:
RuntimePortletUtil.processTemplate(application, request, response, pageContext, out, velocityTemplateId, velocityTemplateContent);
When I do the same in my portlet however, I get the following error as soon as I put any portlets inside the layout template:
[render_portlet_jsp:157] javax.servlet.ServletException: File "/html/portal/render_portlet.jsp" not found
at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:412)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:379)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
Can RuntimePortletUtil only be used in the Liferay portlet context or is there a way to get this working in my own portlet?
It looks like the implementation requires a file /html/portal/render_portlet.jsp which you might not have. It might be as simple as checking that file, see if you only need it or a few more resources.
However, instead of hunting that implementation down, I'd recommend looking at the underlying problem that you'd like to solve: IMHO Layout Templates are by far the easiest plugin types you can have in Liferay. All the examples I've seen for nesting Layout Templates looked more like a quick hack than like a proper solution. My recommendation is to provide some custom layout templates: It typically won't be a huge number of them, as increased numbers of layouts are typically increasingly confusing to the end user.
NestedPortlet is implemented inside Liferay's core and does not make any assumptions about running outside. While it might not be the best architectural decision to implement it depending on the server, nobody paid attention to make that code able to run outside of the portal - do yourself a favor and make your life easier by checking a different solution.

developing library controls for xpages

I' working on a library control for Xpages and need some help in creating.
I would create a control which reads a configuration file and creates controls in a table, controls like Editboxes, checkboxgroups and so on.
so and now to my questions:
could I initiate controls from the Exlib or must I implement them all by my self?
if I could use them from the Exlib could anyone explain me how?
I hope its clear what i mean if not please ask me for further informations.
When creating your own components, if you're closely replicating some behavior that is already in an extension library component, I highly recommend you extend that component and just add what's needed to accommodate your different functionality. This makes things much easier and you don't have to code around every little scenario that the component might be placed in.
But, if you are developing a component that is nothing like any of the extension library or core components then just ensure your component extends UIComponent or UIComponentBase. If going this route, you'll also need to create your own renderer which extends Renderer. This is what will build the on-screen representation of your component. Again, if there's already something in the core components or extension library components that closely mimics what you need then make your renderer extend that renderer. Also, don't forget to include the renderer definition in the faces-config file and the component definition in the xsp-config file or your component won't work.
As for initiating controls from the extlib.... I assume you mean can you inject them onto the page at runtime. If so the answer is absolutely yes. To add an input text field to the page where there is a container (i.e. panel, div, span, whatever) with an ID of "someContainer"
XspInputText input = new XspInputText();
input.setValue("someValue");
input.setId("someID");
UIComponent container = FacesContext.getCurrentInstance().getViewRoot().findComponent("someContainer");
container.getChildren().add(input);
To see the api for all of the core and extension library components take a look at the XPages Controls Documentation. For a more complete tutorial on creating your own components take a look at my blog for creating a custom component inside an nsf, the steps are pretty much the same for putting them into a library:
Part 1,
Part 2 and there is an example database in the Part 2 post.

Resources