Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: Extending a liferay-ui tag
Hi all,
I'm trying to make a custom change to the deletion of Liferay roles, that displays different text in the confirm dialog based on a condition.
I have overridden the jsp page by creating a roles-admin-web-override module, and copied role_action.jsp and view.jsp into its src/main/resources/META-INF.resources/ directory. This works and I can change the confirm text, however it is not dynamic at this stage. I would like to extend the <liferay-ui:icon-delete/> tag, and therefore rewrite it as an <liferay-ui:custom-icon-delete> tag.
To do this, I want to create a new CustomIconDelete.java class that extends IconDeleteTag.java - however, IconDeleteTag is found in util-taglib/src/com.liferay.taglib/ui/ and I don't know how to extend this class, or even if it is possible, as this module isn't found in the Liferay/osgi/modules deployment directory. This way I would be able to override its public String getConfirmation() {...} method to return different messages dynamically at runtime.
This would also require that the liferay-ui.tld file in sdk/project-templates/project-templates-spring-mvc-portlet/src/main/resources.archetype-resources/src/main/webapp/WEB-INF/tld/ be updated with the new tag attributes and pointing its <tag-class> attribute to the correct CustomIconDelete class.
I've been traipsing through as many related questions/solutions as I can find but none seem to cover what I'm trying to achieve. Anybody on here have any ideas? Or know of a better approach?
Thanks
I'm trying to make a custom change to the deletion of Liferay roles, that displays different text in the confirm dialog based on a condition.
I have overridden the jsp page by creating a roles-admin-web-override module, and copied role_action.jsp and view.jsp into its src/main/resources/META-INF.resources/ directory. This works and I can change the confirm text, however it is not dynamic at this stage. I would like to extend the <liferay-ui:icon-delete/> tag, and therefore rewrite it as an <liferay-ui:custom-icon-delete> tag.
To do this, I want to create a new CustomIconDelete.java class that extends IconDeleteTag.java - however, IconDeleteTag is found in util-taglib/src/com.liferay.taglib/ui/ and I don't know how to extend this class, or even if it is possible, as this module isn't found in the Liferay/osgi/modules deployment directory. This way I would be able to override its public String getConfirmation() {...} method to return different messages dynamically at runtime.
This would also require that the liferay-ui.tld file in sdk/project-templates/project-templates-spring-mvc-portlet/src/main/resources.archetype-resources/src/main/webapp/WEB-INF/tld/ be updated with the new tag attributes and pointing its <tag-class> attribute to the correct CustomIconDelete class.
I've been traipsing through as many related questions/solutions as I can find but none seem to cover what I'm trying to achieve. Anybody on here have any ideas? Or know of a better approach?
Thanks

Wouldn't it be easier to just do <c:if /> around two (or more) different options? I mean, sure there are many ways to skin a cat, but I certainly would want to start with the easier ways before I get to the harder ones...
Or is this more like an excercise to understand how you would approach such a thing?
Or is this more like an excercise to understand how you would approach such a thing?
Hi David
Thank you kindly for responding. My problem is that I have to retrieve information about the role by making a REST call to my application. By wrapping this call inside the <c:if> condition, then every time Liferay's roles page is loaded, it would need to make potentially as many as 20 individual REST calls, for each role, in order to pre-load what message would be displayed in the confirm.
If I were able to change the confirm message at runtime, I could change it to execute some javascript that makes an ajax call so that the REST call is only made when the user actually clicks to delete. (Looking further at this I would probably need to change IconDeleteTag's getPage function, and write some javascript that defines a new function taking a role id as argument and returning a confirmation message, then pass this function into the confirm.)
Essentially I'm just trying to find some way that avoids making 20 separate REST calls - hopefully the above makes sense?
Thank you kindly for responding. My problem is that I have to retrieve information about the role by making a REST call to my application. By wrapping this call inside the <c:if> condition, then every time Liferay's roles page is loaded, it would need to make potentially as many as 20 individual REST calls, for each role, in order to pre-load what message would be displayed in the confirm.
If I were able to change the confirm message at runtime, I could change it to execute some javascript that makes an ajax call so that the REST call is only made when the user actually clicks to delete. (Looking further at this I would probably need to change IconDeleteTag's getPage function, and write some javascript that defines a new function taking a role id as argument and returning a confirmation message, then pass this function into the confirm.)
Essentially I'm just trying to find some way that avoids making 20 separate REST calls - hopefully the above makes sense?
<c:if /> is JSP, so it is server side code and therefore does not need to do REST calls, local service calls are just fine.
Also a role check is not normally how Liferay operates, if you used permissions instead then you could just use normal PermissionChecker logic and wouldn't have to make 20 different calls ever.
Finally, if you are planning for your front end to make REST calls to get roles for JS evaluation, I'd argue that is also a wrong path. Instead of making role-checking REST calls, the JSP should pull the user's roles and store as JS data, caching it for future access. Sure there's a small window of chance that a user's roles might change after the portlet is rendered to the browser, but the savings in complexity (all the rest services, etc) will be well worth the risk. Besides, the REST code or Jsonws code should be doing permission checks before allowing stuff anyway, so the change in role would not expose any real risk outside of the UI showing a button that did nothing.
Also a role check is not normally how Liferay operates, if you used permissions instead then you could just use normal PermissionChecker logic and wouldn't have to make 20 different calls ever.
Finally, if you are planning for your front end to make REST calls to get roles for JS evaluation, I'd argue that is also a wrong path. Instead of making role-checking REST calls, the JSP should pull the user's roles and store as JS data, caching it for future access. Sure there's a small window of chance that a user's roles might change after the portlet is rendered to the browser, but the savings in complexity (all the rest services, etc) will be well worth the risk. Besides, the REST code or Jsonws code should be doing permission checks before allowing stuff anyway, so the change in role would not expose any real risk outside of the UI showing a button that did nothing.
Sorry - I'm not sure if I was completely clear. I'm not making Liferay REST calls, they're external REST calls. Basically, the application (Kaleidoscope) has its own database with its own set of roles, and i've developed a mechanism that creates links between these two types of roles (if, for example, a link existed between Kaleidoscope's 'National Dealer' role and Liferay's 'Portal Content Reviewer' role, then when any National Dealer logs in, they will automatically also be assigned the Portal Content Reviewer role).
The difficulty comes because when creating the link, there is an option to delete the Kaleidoscope role if the Liferay role is deleted (this is a requirement). But there needs to be a warning to the user if the Liferay role has any Kaleidoscope roles linked to it that may be deleted as well - hence the external REST call to Kaleidoscope to ask if any such links exist.
Hopefully that explains a bit more about why I'm not actually checking for permissions, as it is for information found on the role that is external to the Liferay API.
The difficulty comes because when creating the link, there is an option to delete the Kaleidoscope role if the Liferay role is deleted (this is a requirement). But there needs to be a warning to the user if the Liferay role has any Kaleidoscope roles linked to it that may be deleted as well - hence the external REST call to Kaleidoscope to ask if any such links exist.
Hopefully that explains a bit more about why I'm not actually checking for permissions, as it is for information found on the role that is external to the Liferay API.
I'm with David -- seems like a lot of work for a message! One of those times where I like to ask the business -- if it was your money, would you be willing to spend XXX dollars on this change? Most of the time the answer is a "hell no".
With that said, the class is in the util-taglib directory in the source, and accord to the bnd the package that the IconDeleteTag is in is actually exported, so you should be able to reference the libs in your module and be confident that they are provided by the OSGI runtime when you deploy. You comment about the jar not being there in the osgi/modules -- it can be a bit of a head scratcher, but, just remember that not everything is found in there. For example, there is stuff in the osgi/core and osgi/marketplace directories as well that you are almost certainly using at runtime.
PS> "lots of ways to skin a cat" ... my God that is a gross expression. Makes me wonder how the heck it every became an expression
With that said, the class is in the util-taglib directory in the source, and accord to the bnd the package that the IconDeleteTag is in is actually exported, so you should be able to reference the libs in your module and be confident that they are provided by the OSGI runtime when you deploy. You comment about the jar not being there in the osgi/modules -- it can be a bit of a head scratcher, but, just remember that not everything is found in there. For example, there is stuff in the osgi/core and osgi/marketplace directories as well that you are almost certainly using at runtime.
PS> "lots of ways to skin a cat" ... my God that is a gross expression. Makes me wonder how the heck it every became an expression

Hi, thanks for the response - as I mentioned in the reply above, the message is a lot of work but tragically is a requirement.
That's useful to know about it being available. I'm pretty new to liferay and overriding it generally, so forgive me for double checking: I think what you're saying is that in my module, I would be able to create in src/com.liferay.taglib/ui/ a class such as CustomIconDeleteTag.java
However I'm still not clear on how to ensure a referenec to the new tag inside liferay-ui.tld would be available? Or is it only possible to override IconDeleteTag, not extend it with a custom version?
That's useful to know about it being available. I'm pretty new to liferay and overriding it generally, so forgive me for double checking: I think what you're saying is that in my module, I would be able to create in src/com.liferay.taglib/ui/ a class such as CustomIconDeleteTag.java
However I'm still not clear on how to ensure a referenec to the new tag inside liferay-ui.tld would be available? Or is it only possible to override IconDeleteTag, not extend it with a custom version?
You can (and should) have only one system of record.
If Kaleidoscope is used to manage roles and mapping, then you shouldn't be allowing role deletion in Liferay in the first place.
If Kaleidoscope is used to manage roles and mapping, then you shouldn't be allowing role deletion in Liferay in the first place.
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™