How to add navigation to a custom Magnolia CMS template? - java

I've managed to create a custom page template for Magnolia CMS pretty easily following this tutorial:
http://documentation.magnolia-cms.com/templates/introduction.html
However, I'm at the point where I'd like to insert the navigation into my template but I can't find a simple way to do so. It looks like other's have had this problem with no clear way to fix it. Does anyone know how to easily include the navigation? Thanks

If you're using Magnolia CE (Community Edition) 4.5.x, you need to know that basically every page template extends the one defined in /modules/standard-templating-kit/config/site/templates/prototype. There you have a node, /navigation. You can copy that node to your new custom template, and after that you can start playing with it's properties.
But before that, don't forget to include the navigation menu(s) somewhere in your main template file (.ftl) and make your template to use stk model class info.magnolia.module.templatingkit.templates.pages.STKPageModel (add an attribute to your template named modelClass, look at stkArticle (or stkSection), it's a good place to start)
Horizontal navigation:
[#if def.navigation.top]
[#include def.navigation.horizontal.template]
[/#if]
Vertical nav:
[#if def.navigation.top]
[#include def.navigation.vertical.template]
[/#if]
If you want to include your menu in another template included with a [#cms.area ...] tag,
you can use this code:
[#if model.root.def.navigation.top]
[#include model.root.def.navigation.vertical.template]
[/#if]

Related

How to redirect user from root node to it's child node in Magnolia CMS

My project is developed using Magnolia 5.3 and Blossom and is using Enterprise Edition - Standard version of magnolia.
I am new for Magnolia and this project.
This project is for different countries and in different languages.
It has the first page for the country and language listing.
For ex. www.localhost:8080 shows this country listing page.
When user clicks on any link of this page, then he is redirected to country home page with chosen language.
For Example:
Country C1 with language L1 has the URL: www.localhost:8080/C1/L1
And this shows the content of country root page i.e. C1
Each country has the same heirarchy in Magnolia CMS
C1 - Root Node of country C1
C1/XYZ1 - Page 1
C1/XYZ2 - Page 2
C2 - Root Node of country C2
C2/XYZ1 - Page 1
C2/XYZ2 - Page 2
and so on.
So if I want to access any root page of country then URL will be:
www.localhost:8080/C1/L1
And If I want to access any child page then URL will be:
www.localhost:8080/C1/L1/XYZ1
This is fine so far.
But now I want to remove or hide the country root page from the user.
So If user manually type www.localhost:8080/C1/L1 then
User should be warn with no page found or
User is redirected to page1 i.e. www.localhost:8080/C1/L1/XYZ1 and show page1 content.
I have tried with setting virtualURIMapping but this do not work.
I also tried to remove C1 page but I can not remove as this is the root page and it is not possible to remove root without it's children.
Please help and guide me, how can I do this?
Thanks,
Manoj
If you are using Enterprise version, all you have to do is configure domain for your site to have it recognized properly and then Magnolia will hide root node automatically from all links.
If you are using Community edition, it's not possible as this feature is only in Enterprise.
However if you instead want to redirect to a subpage of the selected site (as it seems to now after your update of the question), you need to create a virtual URI mapping to do this.
There are many possible ways to create such mapping, one of them would be:
1) in AdminCentral, go to Configuration app and open config:/modules/ui-admincentral/virtualURIMapping\default
2) change class to info.magnolia.multisite.MultiSiteRegexpVirtualURIMapping
3) change fromURI to \$
4) change toUri to redirect:/XYZ1\.html
5) add property site and set it's value to C1 (assuming your site in WebDev/Sites is called C1)
This will work only if you have your domains mapped properly in the site configuration. If you don't get it working on the first try, try to play with it, change the values, double check you have all config correctly. Try to maybe also look in the code of the mapping to make sure you understand how it work. And most importantly, check other VirtualURIMappings you have configured (you can see all in Config Info app).
Additional disclaimer: If you set virtual uri mapping incorrectly (specially since this one is regex based so it is super easy to "expand" it to react on all urls), it is possible to make your instance inaccessible. Make sure when you do this, you do so on your development instance and that you have backup and can go back. Only apply such change on production via importing previously created and tested mapping.
HTH,
Jan

Netbeans Plugin development: #ActionReference paths reference

I am developing a Netbeans plugin which will verify a Web Project against some rules.
I am trying to add it a menu as a first item in the Projects context menu. From what I understand, this is done by specifing the path attribute in the #ActionReference annotation. Anyone knows where to find a complete reference for the possible paths?
This is what I have now, and my Menu item appears somewhere in the bottom of the Projects context menu, so I suspect I need something different than "Projects/Actions"
#ActionID(
category = "Tools",
id = "org.chain.war.WarVerifier")
#ActionRegistration(
displayName = "#CTL_WarVerifier")
#ActionReference(path = "Projects/Actions", position = 0)
public final class WarVerifier implements ActionListener
I am on Netbeans 7.2
Thanks,
Chris.
Right-click on one your package New > Other... and under Module Development choose XML Layer.
This XML Layer will show as a drop down containing 2 elements, choose this layer in context you will have the full hierarchy.

How to remove unwanted menu contributions in eclipse rcp application?

I have made a eclipse RCP application, everything is working fine but i recently noticed the Refractor option in menu. I would like to get rid of it. I have the following in ActionBarAdvisor.java:
#Override
protected void fillMenuBar(IMenuManager menu) {
menu.add(createFile());
menu.add(createEdit());
menu.add(createNavigate());
menu.add(createProject());
menu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
menu.add(createWindow());
menu.add(createHelp());
}
The above functions add actions to menu as:
edit.add(undoAct);
and also undoAct is defined as:
private IWorkbenchAction undoAction
makeActions function has contents as:
#Override
protected void makeActions(IWorkbenchWindow window) {
undoAction = ActionFactory.UNDO.create(window);
undoAction.setText("Undo Menu");
register(undoAction);
}
I found a suggestion which said to use hideActionSets to hide the menu. But I could not hide the entire menu but just its actions!
Remove "File, edit,...etc" menus from Eclipse RCP application
How to remove Refractor option now?
Thank you.
You can use activities, as described here.
First, you will need to find the ID of the menu:
Use the Plug-In Spy
The first way is to use the Plug-In Spy. Press alt-shift-F2 and click on a
menu item or toolbar button that you want to be hidden. If there is an ID
string under the heading "active action definition identifier" then you are
in luck. This item has been added using the Command Extension and you can
use this ID as the pattern argument for the Activities Extension. But not
all items that have been added using the Command Extension present their ID
string to the plug-in spy.
As a side note, the ID strings are period separated. For instance the ID for
a button might be "org.eclipse.ui.navigate.backwardHistory". Regular
expressions use the period to stand for any character. Luckily the period
used as a wild card matches with actual period characters so you don't need
to escape them if you don't want to. I find it makes it a bit easier to read
if they are not escaped and it is highly unlikely it will cause any
ambiguous matches.
Use the Plug-In Registry and plugin.xml files
The second way is to use the Plug-In Registry. You can open this view by
going to:
Window/Show View.../Other/Plug-in Development/Plug-In Registry
What you would like to do is to try to get a couple pieces of information:
a) the plugin that is contributing the UI element
b) information about what kind of extension the plugin is using to create
the UI element
If there is a very unique word associated with the UI element or its tool
tip then you can use this in the Plug-In Registry's filter field to try to
nail down which plug-in is contributing the UI element. The filter field is
not a very powerful tool so it can be a bit frustrating to use. It does not
allow wildcards and does not match space characters.
When you track down which plug-in is contributing the UI element then you
open the the plug-in in question from the Plug-Ins view which is found
grouped with the Package Explorer in the Plug-in Development perspective.
Then go to the Extensions tab and search for the ID string which can usually
be found in either a usage of the Command or ActionSet extension. If the UI
element is added using an ActionSet then you prefix the plug-in ID to UI ID
in the pattern argument given to the Activities Extension. For example
org.eclipse.ui.actionsets.foo becomes the pattern
org.eclipse.ui/org.eclipse.ui.actionsets.foo.
Then create a new Activity which will never be activated and a corresponding activityPatternBinding with the id you found in the last step. It will look like this in your plugin.xml:
<extension point="org.eclipse.ui.activities">
<activity id="myActivity" name="MenuHidingActivity">
<enabledWhen>
<with variable="activePartId">
<equals value="nonExistentPartId"></equals>
</with>
</enabledWhen>
</activity>
<activityPatternBinding activityId="myActivity" pattern="menuItemID">
</activityPatternBinding>
</extension>

How to use GWTQuery-UI

I am trying to unserstand how GWTQuery works, for that I am trying out a simple demo with the slider. As per the documentation at Google (the slider tab is on the bottom left), and using the class AbstractSliderDemo from here, which in turn, is implementing the Demo interface defined here, my onModuleLoad simply contains:
Label e = $("#slider").widget();
Query q = new Query();
q.setupDemoElement(e.getElement());
However on page-load, it is throwing a NullPointer exception. Can anybody guide me how to use it. Probably I am missing something here. (I have added both GWTQuery and GWTQuery-UI jar files to the build path, as well as including <inherits name='gwtquery.plugins.Ui' /> in the XML file).
And here is the directory structure of my project:
GwtQuery-Ui is just a wrapper on jquery-ui. That means that you need to inject the jquery and jquery-ui javascript file. Check the getting started guide og GwtQuery-ui

wicket: mapping different paths to the same class on request to generate different content in markup

I developed a shopsystem. there is a product page, which lists the available items filtered by some select menus. there is also one item detail page to view some content about each product. the content of that page will be loaded out of an xml property file. if one would click the link in the listview of an item, to view some details, an item specific GET parameter is set. with the parameters value, i can dynamically load the content for that specific item from my properties, by altering the loaded keys name.
so far so good, but not really good. so much to the backgroud. lets get to some details.
most of all, this is some SEO motivated stuff. so far there is also a problem with the pageinstance Id in the url for statefull pages, not only because of the nonstable url, also because wicket is doing 302 redirects to manipulate the url. maybe I will remove the statefull components of the item detailpage to solve that problem.
so now there are some QR-code on the products being sold, that contain a link to my detail page. these links are not designed by myself and as you can imagine, they look a whole lot of different like the actual url. lets say the QR-code url path would be "/shop/item1" where item1 would be the product name. my page class would be ItemDetailPage .
I wrote an IRequestMapper that I am mounting in my WebApplication#init() that is resolving the incoming requests URL and checks wether it needs to be resolved by this IRequestMapper. If so, I build my page with PageProvider and return a requesthandler for it.
public IRequestHandler mapRequest(Request request) {
if(compatibilityScore>0) {
PageProvider provider = new PageProvider(ItemDetailPage.class, new ItemIDUrlParam(request.getUrl().getPath().split("/")[1]));
provider.setPageSource(Application.get().getMapperContext());
return new RenderPageRequestHandler(provider);
}
return null;
}
So as you can see, I build up a parameter that my detailpage can handle. But the resulting URL is not very nice. I'd like to keep the original url by mapping the bookmarkable content to it, without any redirect.
My first thought was to implement an URLCodingStrategy to rebuild the URL with its parameters in the form of a path. I think the HybridUrlCodingStrategy is doing something like that.
After resolving the URL path "/shop/item1/" with the IRequestMapper it would look like "/shop/item?1?id=item1" where the first parameter off course is the wicket pageinstance Id, which will most likely be removed as I will rebuild the detail page to be stateless :(
after applying an HybridURLCodingStrategy it might look like "/shop/item/1/id/item1" or "/shop/item/id/item1" without pageinstance Id. another Idea would be to remove the second path part and the parameter name and only use the parameters value so the url would look like "/shop/item1" which is then the same url as it was in the request.
Do you guys have any experience with that or any smart ideas?
The rewuirements are
Having one fix URL for each product the SE bot can index
no parameters
stateless and bookmarkable
no 302 redirects in any way.
the identity of the requested item must be available for the detailpage
with kind regards from germany
Marcel
As Bert stated, your use case should be covered with normal page mounting, see also the MountedMapper wiki page, for your case a concrete example:
mountPage("/shop/${id}", ShopDetailPage.class);
Given that "item1" is the ID of the item (which is not very clear to me), you can retrieve it now as the named page parameter id in Wicket. Another example often seen in SEO links, containing both the unique ID and the (non-unique, changing) title:
mountPage("/shop/${id}/${title}", ShopDetailPage.class);
Regarding the page instance ID, there are some ways to get rid of it, perhaps the best way is to make the page stateless as you said, another easy way is to configure IRequestCycleSettings.RenderStrategy.ONE_PASS_RENDER as the render strategy (see API doc for consequences).

Categories