Add a item / page in the portlet admin menu in Liferay - liferay

I want to add an other item in the admin menu in a portlet.
For example, add an item "Organization" between Apparence and Configuration.
Is it possible ??
However, i tested a new configuration page in the Configuration menu.
So i add in portlet.xml :
<init-param>
<name>config-jsp</name>
<value>/html/foo/configuration.jsp</value>
</init-param>
in liferay-portlet.xml :
<configuration-action-class>com.projecto.ec.config.ConfigurationActionFooImpl</configuration-action-class>
and my ConfigurationActionPrenalyticImpl looks like this :
public class ConfigurationActionPrenalyticImpl implements ConfigurationAction {
#Override
public void processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
// TODO Auto-generated method stub
}
#Override
public String render(PortletConfig portletConfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
return "/html/preanalytic/configuration.jsp";
}
}
But i don't know how to init correctly this page with some content like in a doView or doEdit.

I'd say it is possible, but is none of the standard extension paths that you typically would go within Liferay. A standard way would be to either implement the JSR-286 "edit" mode or contribute another configuration page to the Liferay-specific configuration.
I've never seen the extension you're intending to do in the wild, and I'm assuming that it would require some poking in the internals. It's most likely not well documented. Given that 6.x is the last release that does not use OSGi (and everything will change with Liferay 7 / DXP), I'm not sure if I should recommend going this way.

Related

How to intercept JSF view resolving in order to replace the outcome page?

A certain managed bean has an action method that returns "/private/myview.jsf". However, without changing this code, I want to perform some checks and eventually render the view "/private/other/myview.jsf".
So, in summary, I want to translate "/private/myview.jsf" to "/private/other/myview.jsf" somewhere after the method return and before the actual view rendering.
How to achieve that?
Environment:
Eclipse Luna
Java 1.7
JSF 2
Current condition
Web application fully operational but not developed to support accessibility features.
Requirement for the next version
To be an application good enough to be used by blind people who uses screen readers.
Details
After some study, we reached the conclusion that we will have to have an accessible version of each page we have nowadays.
We will design such accessible version of each page, the matter is when to show the not accessible version and when to show the accessible version.
We decided that the application will turn to accessible mode (that will not be the default state) when the user clicks a certain link in the top of the page. In accessible mode, only accessible versions of pages are rendered.
We don't want to review all the application, what we want is to intercept some phase of JSF and replace the outcome that should be rendered. For instance, consider the follow:
A certain page has a link or a button to another one, let's say "mysettings.xhtml";
When in accessible mode, we would like to tell to JSF to not render "mysettings.xhtml", instead "mysettings_ac.xhtml" or "accessible/mysettings.xhtml" should be rendered;
Both pages will interact with the very same managed beans and will provide the very same features, but one will be good to the ones who can see and the other will be designed to be comfortable to screen reader users.
Thanks in advance!
So, in summary, I want to translate "/private/myview.jsf" to "/private/other/myview.jsf" somewhere after the method return and before the actual view rendering.
If you're already on JSF 2.2, you can do this by providing a custom ResourceHandeler wherein you return the desired view resource in createViewResource() based on some condition.
public class YourResourceHandler extends ResourceHandlerWrapper {
private ResourceHandler wrapped;
public YourResourceHandler(ResourceHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public ViewResource createViewResource(FacesContext context, final String name) {
if (someCondition) {
name = name.replace("/private/", "/private/other/");
}
return super.createViewResource(context, name);
}
#Override
public ResourceHandler getWrapped() {
return wrapped;
}
}
Which is registered in faces-config.xml as below:
<application>
<resource-handler>com.example.YourResourceHandler</resource-handler>
</application>
Or if you're not on JSF 2.2 yet, then use ResourceResolver instead.
public class YourResourceResolver extends ResourceResolver {
private ResourceResolver parent;
public YourResourceResolver(ResourceResolver parent) {
this.parent = parent;
}
#Override
public URL resolveUrl(String path) {
if (someCondition) {
path = path.replace("/private/", "/private/other/");
}
return parent.resolveUrl(path);
}
}
Which is registered in web.xml as below:
<context-param>
<param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
<param-value>com.example.YourResourceResolver</param-value>
</context-param>
As I can see, there can be two probable solutions to it.
using redirect() method
returnAction(){
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect("/private/other/myview.jsf"); //Relative path might vary based upon your business logic
}
conditional redirect after action return; we can maintain a navigation rule in faces-config.xml something like below:
<navigation-rule>
<navigation-case>
<from-action>#{yourManagedBean.actionMethod}</from-action>
<if>#{yourManagedBean.redirectAccessibleFlag}</if> <!-- We maintain a boolean variable redirectAccessibleFlag in the managed Bean and set its value to true or false conditionally-->
<to-view-id>/private/other/myview.jsf</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
In the second alternative, you can put up the managed bean at ApplicationScope in order to be utilized across multiple JSF pages.
Although these solutions are from the general concepts, they might not necessarily fall in the "somewhere after the method return and before the actual view rendering." But you can check if it solves the purpose.

javafx2.0 - force refresh the scene

In my app, one scene having the popup dialog which consists of some fields and buttons. If you click on the button then I want to dismiss the popup dialog as well as update the some fields in the scene. Indirectly I want to refresh scene. is it possible?
I used the following code.Here what I did is, I get the controller of that scene and then update the field using id. but it doesn't work.
URL location = AdmincontrolController.class.getResource("admincontrol.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
Parent root = (Parent) fxmlLoader.load(location.openStream());
AdmincontrolController controller = fxmlLoader.getController();
System.out.println("AdmincontrolController: "+controller);
controller.setEmail(item.getEmail());
} catch (IOException ex) {
Logger.getLogger(Add_loginController.class.getName()).log(Level.SEVERE, null, ex);
}
Scenario:
scene
Popup - If we clicks on the add then we need to dismiss that dialog and change the email text on the previous scene.
As Alexander mentioned above, updating the underlying text property of the object you are using to display the email should Just Work. You need to make sure that you are working with the property (see Oracle Java FX Property Tutorial for more info). As a concrete example:
FXML
<Text fx:id="email" />
<TextField fx:id="emailInput" />
<Button onAction="#doSetEmail" text="Set Email"/>
In your controller, use the #FXML annotation to inject concrete instances of objects and set the handler to adjust the text:
Controller
#FXML
Text email;
#FXML
TextField emailInput;
#FXML
public void doSetEmail(ActionEvent ae) {
email.setText(emailInput.getText());
}
Alternatively, you could just bind the email text property to the email label property so that changes would automatically get propagated:
email.textProperty().bind(emailInput.textProperty());
You could do this in your controller initialize() method.
Now, the caveat to all this working depends on how you are handling the event and what you are doing in this. You still haven't posted the code for that as requested by the first answer, so you may be having issues there. Namely, if you are starting threads and then trying to update UI elements on the JavaFX thread from a worker thread, then you can get into trouble (potentially) with things not updating. This depends substantially on the structure of your objects, and you have not given enough information to comment in any meaningful way on that.
chooks
Everytime you have the Feeling that you manually want to update a Scene you should probably use a backgroundWorker Thread to do the work.
This way your UI Thread can use the time to update Labels etc.
JavaFX is built so that you don't need to directly call the scene update routine. All you need - update properties of scene components, and they will be updated on the nearest pulse.
So, all you need is to update properties. Or, is there any real trouble?
refreshing scene its not possible without closing...but if you can do class level declaration for control..i.e make them static its may work...
try this..
make a function in main file.
MainPanel.java
public static void SetMail(String email)
{
txtmail.setText(email);
}
LoginPanel.java
btnclear.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
MainPanel.SetMail(txtEmail.getText());
}
});

How can I extract the main body of an Orchard Page via a Url

What I'm looking to do is have 2 views of an orchard page.
The first will include headers and footers, the second just the main body content.
The reason is so that we can maintain the body in one place, and it will be used either as a stand alone site, or just embedded within another.
I'm thinking that it would be done by accessing the page using a different route, or appending a querystring parameter.
Any other options are welcomed.
The method I am about to describe is arguably a hack and may go against some of the intentions of the creators of Orchard, but it will get the job done.
Orchard uses the ThemeFilter with the Themed attribute to decide whether the current controller action's output will be 'themed' --- i.e., be displayed with headers and footers. The controller used by Orchard to display content items has this attribute enabled, which is why content items are displayed themed. What you are asking to do is to suppress this 'themed' mode based on the presence of a query string parameter.
ThemeFilter kicks in at a very early stage of the page request and applies itself by setting a value in the current request's http context.
ThemeFilter.cs:
public static void Apply(RequestContext context) {
// the value isn't important
context.HttpContext.Items[typeof (ThemeFilter)] = null;
}
This class does not provide a way of unApplying this value. If you are willing to modify the Orchard source code, you may add this method yourself:
public static void Unapply(RequestContext context) {
context.HttpContext.Items.Remove(typeof (ThemeFilter));
}
Then you can simply create your own action filter that checks for the existence of a query string and then call this method if appropriate, something like:
using System.Web.Mvc;
using Orchard.Mvc.Filters;
using Orchard.Themes;
namespace Demo {
public class UnthemeFilter : FilterProvider, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
}
public void OnActionExecuted(ActionExecutedContext filterContext) {
if (filterContext.RequestContext.HttpContext.Request["unthemed"] != null) {
ThemeFilter.Unapply(filterContext.RequestContext);
}
}
}
}
Now by adding ?unthemed=true, you will be able to suppress the theming.
If you are unwilling or unable to modify the Orchard source code, it is still possible to do the same thing by directly removing the typeof (ThemeFilter) from the HTTP context in your filter. However, this breaks encapsulation and should probably be avoided in object-oriented programming.

What is the difference between super.doView(...) and include(...) on doView override?

I am developing a custom portlet (EDIT:I'm extending MVCPortlet), and looking at several examples and tutorials, I find that when the doView(RenderRequest, RenderResponse) method is overridden, at the end of it there is always at least this line:
super.doView(renderRequest, renderResponse);
or this:
include(viewJSP, renderRequest, renderResponse);
If I don't put either of these my portlet doesn't render anything, but any of them does the trick.
I would like to know which one I should be using, and why do I need to add them to get my portlet to work.
Thanks!
So you must be extending MVCPortlet class. Both the calls are used to include the JSP after the doView processing is completed. If you look at the source code of this class then you would understand what the flow is, below is my explanation:
super.doView(renderRequest, renderResponse);
This includes the default JSP i.e. view.jsp, that you might (or not) have configured in portlet.xml something like this:
<init-param>
<name>view-template</name>
<value>/html/view.jsp</value>
</init-param>
This super class method does nothing but calls the include(viewJSP, renderRequest, renderResponse); method at the end.
include(viewJSP, renderRequest, renderResponse);
This method includes whatever JSP path you have specified for the parameter viewJSP. So with this call you can specify including different JSP for different condition something like the following:
if (isThisTrue) {
include("/html/myCustomPortlet/view.jsp", renderRequest, renderResponse);
} else if (isThisTrueThen) {
include("/html/myCustomPortlet/first/another_view.jsp", renderRequest, renderResponse);
} else {
super.doView(renderRequest, renderResponse);
}
So depending on your requirement you can use any to the two or the mix of the two as shown above. Hope this helps.
The include lets you specify a different JSP to use instead of the default view. So if you are not using a custom view page either will work.

Add a conf menu to my portlet

I'm trying to add a tab in the conf of my custom portlet, beside the natives import/export and permissions.
Like in this image : http://imageshack.us/photo/my-images/716/sampledn.png/
This tab had to allow, to change the value of a parameter in a conf.properties which define some variable.
How can I do that?
Regards.
Yup you can do it by first of all adding this to your portlet.xml as a child of the "portlet" node:
<init-param>
<name>config-jsp</name>
<value>/html/config.jsp</value>
</init-param>
The in your liferay-portlet.xml you need to add this as a child of the "portlet" node:
<configuration-action-class>com.yourportlet.action.ConfigurationActionImpl</configuration-action-class>
Then you need to create this files in the directories you've specified in your XML, and your ConfigurationActionImpl should implement the ConfigurationAction interface so the skeleton would look like this:
public class ConfigurationActionImpl implements ConfigurationAction {
#Override
public String render(PortletConfig config, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
return "/html/config.jsp";
}
Let me know if this helps or you have any other questions! :)
Add edit mode to your portlet.xml:
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode> <!-- add this line -->
</supports>
Then you will see preferences option in the menu. Override doEdit method in your portlet class to render content of the edit mode.
EDIT:
More advanced solution:
You can add another tab by changing portal jsp via hook. The jsp you need to change is:
/html/portlet/portlet_configuration/tabs1.jsp
Note that this will change configuration window for ALL portlets.

Resources