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
How to Integrate the Custom Search Portlet to the Theme
Hi ,
I have a custom search portlet which does the following thing
Now I need to integrate my custom search protlet to the theme . I need to know the following thing :
I have add the attachment how it should be.
Does anyone know how to do this?
Regards,
Avinash
I have a custom search portlet which does the following thing
- Allow user to enter the keyword and submit the form to display the result in the new JSP File.
- In the backend we call the third party API to fetch the result in the Json format and display the result in the Page after the form submit.
Now I need to integrate my custom search protlet to the theme . I need to know the following thing :
- Code to add in the Theme portal_normal.vm to display custom portlet in theme . i.e with search box and submit button
- To display the result in the Portal content area .
I have add the attachment how it should be.
Does anyone know how to do this?
Regards,
Avinash
I see two ways:
a) You create a dedicated results page and post/send the form to that page. A "my-search-results" portlet picks up the query or post parameters and shows the results. You actually don't need to embed portlet in the header here, just a little form. If the entered text is simple enough, you could even use a simple link with a GET parameter.
b) You do the search using ajax and replace the current page content with the search results. Or display it in an overlay. I'd be careful with that, it might be bad for the user experience (e.g. the back button won't work "correctly" since there was never a page change).
For one customer we just link to "/search#/<searchtext>" in the header form. On that page, the #/text is read by a vue.js application and the search results are fetched and displayed using rest. You can try it here:
https://ams.com/
a) You create a dedicated results page and post/send the form to that page. A "my-search-results" portlet picks up the query or post parameters and shows the results. You actually don't need to embed portlet in the header here, just a little form. If the entered text is simple enough, you could even use a simple link with a GET parameter.
b) You do the search using ajax and replace the current page content with the search results. Or display it in an overlay. I'd be careful with that, it might be bad for the user experience (e.g. the back button won't work "correctly" since there was never a page change).
For one customer we just link to "/search#/<searchtext>" in the header form. On that page, the #/text is read by a vue.js application and the search results are fetched and displayed using rest. You can try it here:
https://ams.com/
Thanks for the response .
I do have a dedicated result page for my custom portlet . The situtation is like this
I need to show the text field and search button across all pages so I need to add that in the theme .
Then once the user search for some keywords it should call the api to show suggestions via ajax whose code is in the portlet.
Then based on suggestion kewords user selects the keyword and click on submit button then the result should be displayed in the portal via the custom portlet .
Now if I go with your approach 1 can you suggest how to do this ?
Now my custom portlet works well a a normal portlet application but I need to make this available across all page header so user need not required to add it . So I need to integrate it with my Theme.
let me know if you can help me something with this
I do have a dedicated result page for my custom portlet . The situtation is like this
I need to show the text field and search button across all pages so I need to add that in the theme .
Then once the user search for some keywords it should call the api to show suggestions via ajax whose code is in the portlet.
Then based on suggestion kewords user selects the keyword and click on submit button then the result should be displayed in the portal via the custom portlet .
Now if I go with your approach 1 can you suggest how to do this ?
Now my custom portlet works well a a normal portlet application but I need to make this available across all page header so user need not required to add it . So I need to integrate it with my Theme.
let me know if you can help me something with this
For autocomplete:
You need a rest service (or maybe you could use serveResource for that).
In the above website, we use a rest service. The user types and we send a backend request to fetch a list of suggestions.
We don't use a portlet here, the searchbox is a vue.js application and everything is done through rest calls. For the actual page, we link to the results page.
You can also embed a portlet with your search box. Portlet or not, you need to implement such a javascript method for autocomplete to work.
https://dev.liferay.com/en/develop/tutorials/-/knowledge_base/7-0/embedding-portlets-in-themes-and-layout-templates
Then you link to the search results page (probably you specify the url in the configuration of your portlet). There you read the search parameter and display the results.
You need a rest service (or maybe you could use serveResource for that).
In the above website, we use a rest service. The user types and we send a backend request to fetch a list of suggestions.
We don't use a portlet here, the searchbox is a vue.js application and everything is done through rest calls. For the actual page, we link to the results page.
You can also embed a portlet with your search box. Portlet or not, you need to implement such a javascript method for autocomplete to work.
https://dev.liferay.com/en/develop/tutorials/-/knowledge_base/7-0/embedding-portlets-in-themes-and-layout-templates
Then you link to the search results page (probably you specify the url in the configuration of your portlet). There you read the search parameter and display the results.
Hi Avinash,
I have done something very similar with 6.2, 7.0 and 7.1 -- each is slightly different from the next. Can I ask which version you are using? (I didn't see a reference as I scanned the question).
Christoph's advice is bang on. In 6.2 I used a service, in 7.0 I did this registering an MVCResourceCommand against the search portlet and in 7.1, you can use the same solution as 7 for the type ahead but the results on a separate page got really easy if you use the new search portlets in place of the old Search Monolith.
Happy to share more if you like, but please clarify the versoin for me first.
I have done something very similar with 6.2, 7.0 and 7.1 -- each is slightly different from the next. Can I ask which version you are using? (I didn't see a reference as I scanned the question).
Christoph's advice is bang on. In 6.2 I used a service, in 7.0 I did this registering an MVCResourceCommand against the search portlet and in 7.1, you can use the same solution as 7 for the type ahead but the results on a separate page got really easy if you use the new search portlets in place of the old Search Monolith.
Happy to share more if you like, but please clarify the versoin for me first.
Hi Andrew ,
,
I am using liferay 6.2 . I have everything working as a portlet . The issue is I need to make it work after embeding in the theme .
Any Suggestion will be very helpful .
,
I am using liferay 6.2 . I have everything working as a portlet . The issue is I need to make it work after embeding in the theme .
Any Suggestion will be very helpful .
I see -- well, in that case, since it's all custom, you could use the same approach that Liferay does with their search portlet.
1. Embed your portlet in your theme using the <@liferay_portlet["runtime"] portletName="<your portlet name here>" />
2. When the search is invoked, use a RENDER URL (not an action url, it shouldn't be an action url anyway since you're not changing any data) and render the portlet in a window state of MAXIMZED
.. that way your portlet will render in the content area of the page. As I said, this is actually the same solution that Liferay uses for it's out of the box portlet so I would definitely suggest you have a look at it (in the source)
1. Embed your portlet in your theme using the <@liferay_portlet["runtime"] portletName="<your portlet name here>" />
2. When the search is invoked, use a RENDER URL (not an action url, it shouldn't be an action url anyway since you're not changing any data) and render the portlet in a window state of MAXIMZED
.. that way your portlet will render in the content area of the page. As I said, this is actually the same solution that Liferay uses for it's out of the box portlet so I would definitely suggest you have a look at it (in the source)
In that case, you are pretty much stuck with the serveResource option for loading the autocomplete suggestions.
In 6.2 I would create two portlets.
1) Portlet one is for the header
2) it needs a serveResource implementation and javascript to show autocomplete suggestions
3) In config, you specify a url for the results page
4) Embed that portlet in the page header
5) Portlet 2 shows the results (and maybe has also a search field)
6) I would add public render parameters. With them, you can send parameters from one portlet to the second one*
http://liferayway.blogspot.com/2015/04/ipc-public-render-parameters-example-in.html
7) Add that portlet to the results page
8) The portlet reads the public render parameters and displays the results
*) There are other solutions like creating a link to the second portlet or reading the parameters from the original portlet request.
In 6.2 I would create two portlets.
1) Portlet one is for the header
2) it needs a serveResource implementation and javascript to show autocomplete suggestions
3) In config, you specify a url for the results page
4) Embed that portlet in the page header
5) Portlet 2 shows the results (and maybe has also a search field)
6) I would add public render parameters. With them, you can send parameters from one portlet to the second one*
http://liferayway.blogspot.com/2015/04/ipc-public-render-parameters-example-in.html
7) Add that portlet to the results page
8) The portlet reads the public render parameters and displays the results
*) There are other solutions like creating a link to the second portlet or reading the parameters from the original portlet request.
... AND! .. i would also consider, if you want it to be super AJAX-Y to use the Liferay.fire / Liferay.on. That way if you are on a page where the portlet is in teh header and you have the results portlet on the same page as well (or at least you expect it to be there) you can Liferay.fire the results and Liferay.on in the results portelt to avoid re-rendering the page altogether. I've used that trick in the past and it makes for a pretty slick user experience, but it does require a bit of DOM manipulation, especially if you are updating facets, labels with record counts etc.
Thanks for your reply .
I see some options like to have the form in submit button in one portlet. And autosuggestion also.
And to display the results in the another portlet when the form is submitted .
Do you have any example project or code where you do this scenario ?
Also I am thinking to have both the portlet in the same war file.
Can you share the example code or project which has end to end solution it will be great.
Regards,
Avinash
I see some options like to have the form in submit button in one portlet. And autosuggestion also.
And to display the results in the another portlet when the form is submitted .
Do you have any example project or code where you do this scenario ?
Also I am thinking to have both the portlet in the same war file.
Can you share the example code or project which has end to end solution it will be great.
Regards,
Avinash
Hi Avinash,
Unfortunately I can't share the code because it's not really mine to share. I mean I wrote it, but it belongs to my client so without their permission I can't give it to you. I can however tell you what I did. My approach was a little different from yours though as I did use the Liferay Search portlet for this solution. The concepts though woul dbe the same -- you'd just have to apply them to your portlet(s).
First off I think you should consider Christoph's responses as well. It certainly sounds like you could benefit from a second portlet (one for the header, one for the results) and then, as he said, configure a public render parameter on the keywords to share the value entered by the user across any portlet. I have an alternative (one portlet) option but let me describe what I did for this other project first.
1. JSP Hook on teh JSP used to render the "search bar" -- and in here I added some JS code to the fields so that when the (configurable) threshold of 3 characters or more was reached, my JS function would fire. I used AUI for this.
2. My AUI function crafted a URL to hit, passing the goupId (for site scope) and the keywords
3. I would have to dig up the code, but since this was a public URL I'm pretty sure I just used a StrutsAction. I invoked the struts action using AJAX with the parameters.
4. The struts action received the request and then, in my case, used Liferay's search API to perform a search
5. I wrapped the results in a JSON object and sent back
6. In the JSP I parsed the JSON response and if there was anything there, showed the drop down.
7. When the user hit enter, either after selecting from the drop down or not, I used a dynamically generated RenderURL to send them to a preconfigured destination for search results -- /search
8. The parameter I used in the render request was the one the Search Portlet looks for and since it found keywords, it would perform the full search and render the results.
Now, in the case of #8, the search bar then moved from the header to just above the results because that is how it renders. We did some magic to hide that "full view form field" and instead move it back into the header.
In your case though, as an alternative. You could do everything from 1 - 6 in your theme with just a regular form field. For the button on the form field you could do #7 -- create a render url to take you to a predefined page and include the keywords. Then on the predefined page you just drop un your custom portlet and perform the search, and show the results.
Hope this makes sense.
Unfortunately I can't share the code because it's not really mine to share. I mean I wrote it, but it belongs to my client so without their permission I can't give it to you. I can however tell you what I did. My approach was a little different from yours though as I did use the Liferay Search portlet for this solution. The concepts though woul dbe the same -- you'd just have to apply them to your portlet(s).
First off I think you should consider Christoph's responses as well. It certainly sounds like you could benefit from a second portlet (one for the header, one for the results) and then, as he said, configure a public render parameter on the keywords to share the value entered by the user across any portlet. I have an alternative (one portlet) option but let me describe what I did for this other project first.
1. JSP Hook on teh JSP used to render the "search bar" -- and in here I added some JS code to the fields so that when the (configurable) threshold of 3 characters or more was reached, my JS function would fire. I used AUI for this.
2. My AUI function crafted a URL to hit, passing the goupId (for site scope) and the keywords
3. I would have to dig up the code, but since this was a public URL I'm pretty sure I just used a StrutsAction. I invoked the struts action using AJAX with the parameters.
4. The struts action received the request and then, in my case, used Liferay's search API to perform a search
5. I wrapped the results in a JSON object and sent back
6. In the JSP I parsed the JSON response and if there was anything there, showed the drop down.
7. When the user hit enter, either after selecting from the drop down or not, I used a dynamically generated RenderURL to send them to a preconfigured destination for search results -- /search
8. The parameter I used in the render request was the one the Search Portlet looks for and since it found keywords, it would perform the full search and render the results.
Now, in the case of #8, the search bar then moved from the header to just above the results because that is how it renders. We did some magic to hide that "full view form field" and instead move it back into the header.
In your case though, as an alternative. You could do everything from 1 - 6 in your theme with just a regular form field. For the button on the form field you could do #7 -- create a render url to take you to a predefined page and include the keywords. Then on the predefined page you just drop un your custom portlet and perform the search, and show the results.
Hope this makes sense.
Hi All ,
I was able to embed my custom search portlet to the theme header by adding the below code in the portal_normal.vm file
Can someone tell me how to fix this ?
Also is there any ways by which I can persit my search portlet search box in the header after displaying the result ?
Regards,
Avinash
I was able to embed my custom search portlet to the theme header by adding the below code in the portal_normal.vm file
#set ($see_search_portlet_url = $portletURLFactory.create($request, "MySearchPortlet_WAR_liferaymysearchportlet", $page.getPlid(), "RENDER_PHASE"))
$see_search_portlet_url.setWindowState("maximized")
$see_search_portlet_url.setPortletMode("view")
$velocityPortletPreferences.setValue("portlet-setup-show-borders", "false")
$theme.runtime("MySearchPortlet_WAR_liferaymysearchportlet", "", $velocityPortletPreferences.toString())
The portlet is loaded also with the search box and submit button . But After the search result is displayed in the result page in the portal content area . the search box in the theme header is removed .Can someone tell me how to fix this ?
Also is there any ways by which I can persit my search portlet search box in the header after displaying the result ?
Regards,
Avinash
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™