Magnolia HierarchyManager and Content are depreciated. How do I replicate functionality using Session and jcrNode? - content-management-system

I'm trying to do some logic in my Spring controller where I route to a website node based on the template used in another website node.
I can use LifeTimeJCRSessionUtil.getHierarchyManager("website").getContent("mynodepath").getTemplate() to do this, but I see that the HierarchyManager and Content classes are depreciated.
I looked at the Session class, but I have thus far been unable to figure out how to get the Template id based on the jcrNode.

You can use instead:
javax.jcr.Session jcrSession = LifeTimeJCRSessionUtil.getSession("website");
Node mynode = jcrSession.getNode("/my/node/path");
info.magnolia.cms.core.MetaData metaData = info.magnolia.jcr.util.MetaDataUtil.getMetaData(mynode);
String template = metaData.getTemplate();
Basically, instead of getHierarchyManager("website").getContent("mynodepath") you should use
getSession("website").getNode("/my/node/path").

Related

Create a link in backend to a frontend page

I would link to create a link to a frontend page inside a backend module.
Using:
<f:link.page pageUid="40" >Link</f:link.page>
Doesn't work. It generates a link to the current backend module.
Any solution ?
Since TYPO3 v9 you can use the following lines of code:
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Routing\PageRouter;
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
$site = $siteFinder->getSiteByPageId($pageId);
$router = $site->getRouter();
$frontendUrl = (string) $router->generateUri($pageId);
Thanks to Benni Mack # TYPO3Camp Mitteldeutschland
This is a very long story but the gist is: it is not possible to create FE links in BE/CLI context without a lot of workarounds and dummy objects/values.
If possible you should use solutions like pagepath which generate URLs for an eID script which performs the actual URL generation on demand.

load only components scripts that are in the current page

What I'm trying to achieve is that if i have 2 components nodes :
component1
clientlib
component1.js
component2
clientlib
component2.js
and i drag them into page1, then when page1 is generated, only component1.js and component2.js will be loaded when navigating to page1 .
One approach i saw is to use custom Tag Library as described here : http://www.icidigital.com/blog/best-approaches-clientlibs-aem-part-3/
I have two questions :
1) is there an existing feature in AEM to do this ?
2) if not, what is the easiest way to create such custom Tag Library ?
EDIT:
Assume that there is no ability to just include all component clientLibs, rather load only those that are added to the page.
There is no built in feature to do this. Although I've heard that the clientlib infrastructure is being looked at for a re-write so I'm optimistic that something like this will be added in the future.
We have, and I know other company have, created a "deferred script tag." Ours is a very simple tag that take a chunk of html like a clientlib include, add it to a unique list and then on an out call at the footer, spits it all out one after another.
Here's the core of a simple tag implementation that extends BodyTagSupport. Then in your footer grab the attribute and write it out.
public int doEndTag() throws JspException {
SlingHttpServletRequest request = (SlingHttpServletRequest)pageContext.getAttribute("slingRequest");
Set<String> delayed = (Set<String>)request.getAttribute(DELAYED_INCLUDE);
if(delayed == null){
delayed = new HashSet<String>();
}
if(StringUtils.isNotBlank(this.bodyContent.getString())){
delayed.add(this.bodyContent.getString().trim());
}
request.setAttribute(DELAYED_INCLUDE, delayed);
return EVAL_PAGE;
}
Theoretically the possible way of doing is to write script in your page component/abstract page component that does something like this -
Step1 : String path = currentPage.getPath()
Step2 : Query this path for components (one way is to have a master list do a contains clause on sling:resourceType)
Step 3: User resource resolver to resolve the resourceType in Step 3, this will give you resource under your apps.
Step 4: From the above resource get the sub-resource with primary type as cq:ClientLibraryFolder
Step 5: from the client libs resource in Step 4 get the categories and include the JS from them
you could actually write a model to adapt a component resource to a clientLibrary to actually clean the code.
Let me know if you need actual code, I can write that in my free time.

Creating an AGSStopGraphic,Routing ios

Trying to do routing with ARCGIS SDK for ios.I have a AGSPoint with me as
AGSSpatialReference *sr = [AGSSpatialReference spatialReferenceWithWKID:102100];
AGSPoint *myMarkerPoint =[AGSPoint pointWithX:-13626235.170442
y:4549170.396625 spatialReference:sr];
I have to make AGSStopGraphic with respect to this point ,How it can be done?This is something basic ,But don't know how to do it.
And how to do routing with this?Is there a better approch
You need to create an AGStopGraphic using the AGSPoint. Your myMarkerPoint is a geometry that defines the location. Something like this:
AGSPictureMarkerSymbol* destSymbol = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImage:[UIImage imageNamed:#"RedPin.png"]];
AGSStopGraphic* stop = [AGSStopGraphic graphicWithGeometry:myMarkerPoint
symbol:destSymbol
attributes:{#"Destination" : #"Name"}];
To do the routing request, you need to start with an AGSRouteTaskParameters object and add the stops to it (along with all the other parameters) using the setStopsWithFeatures: method. Then using your AGSRouteTask object, call the method solveWithParameters: and pass it the route task parameters.
According to the AGSRouteTask documentation there is a Routing sample app that you can look at.

How to obtain wicket URL from PageClass and PageParameters without running Wicket application (i.e. without RequestCycle)?

In my project, there are additional (non-wicket) applications, which need to know the URL representation of some domain objects (e.g. in order to write a link like http://mydomain.com/user/someUserName/ into a notification email).
Now I'd like to create a spring bean in my wicket module, exposing the URLs I need without having a running wicket context, in order to make the other application depend on the wicket module, e.g. offering a method public String getUrlForUser(User u) returning "/user/someUserName/".
I've been stalking around the web and through the wicket source for a complete workday now, and did not find a way to retrieve the URL for a given PageClass and PageParameters without a current RequestCycle.
Any ideas how I could achieve this? Actually, all the information I need is somehow stored by my WebApplication, in which I define mount points and page classes.
Update: Because the code below caused problems under certain circumstances (in our case, being executed subsequently by a quarz scheduled job), I dived a bit deeper and finally found a more light-weight solution.
Pros:
No need to construct and run an instance of the WebApplication
No need to mock a ServletContext
Works completely independent of web application container
Contra (or not, depends on how you look at it):
Need to extract the actual mounting from your WebApplication class and encapsulate it in another class, which can then be used by standalone processes. You can no longer use WebApplication's convenient mountPage() method then, but you can easily build your own convenience implementation, just have a look at the wicket sources.
(Personally, I have never been happy with all the mount configuration making up 95% of my WebApplication class, so it felt good to finally extract it somewhere else.)
I cannot post the actual code, but having a look at this piece of code will give you an idea how you should mount your pages and how to get hold of the URL afterwards:
CompoundRequestMapper rm = new CompoundRequestMapper();
// mounting the pages
rm.add(new MountedMapper("mypage",MyPage.class));
// ... mount other pages ...
// create URL from page class and parameters
Class<? extends IRequestablePage> pageClass = MyPage.class;
PageParameters pp = new PageParameters();
pp.add("param1","value1");
IRequestHandler handler = new BookmarkablePageRequestHandler(new PageProvider(MyPage.class, pp));
Url url = rm.mapHandler(handler);
Original solution below:
After deep-diving into the intestines of the wicket sources, I was able to glue together this piece of code
IRequestMapper rm = MyWebApplication.get().getRootRequestMapper();
IRequestHandler handler = new BookmarkablePageRequestHandler(new PageProvider(pageClass, parameters));
Url url = rm.mapHandler(handler);
It works without a current RequestCycle, but still needs to have MyWebApplication running.
However, from Wicket's internal test classes, I have put the following together to construct a dummy instance of MyWebApplication:
MyWebApplication dummy = new MyWebApplication();
dummy.setName("test-app");
dummy.setServletContext(new MockServletContext(dummy, ""));
ThreadContext.setApplication(dummy);
dummy.initApplication();

Rewrite Route to map to default route

Because of the problems I experienced here: Zend_ Controller_ Router_Exception: “xyz” is not specified
I want to have this route:
":module/:controller/:id"
and map it onto this:
":module/:controller/:action/id/$id"
Is there any possibility to do this with Zend Framework? I do not want to forward the browser to that URL. I just want to tell Zend Framework how to handle this route.
As for reasons why I would like to do this, you can find them in that linked SO question.
Yes it is possible. In my application.ini I specify my routes using regex this way:
resources.router.routes.something.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.something.route = "mymodule/mycontroller/([0-9]+)"
resources.router.routes.something.defaults.module = "mymodule"
resources.router.routes.something.defaults.controller = "mycontroller"
resources.router.routes.something.defaults.action = "myaction"
resources.router.routes.something.map.1 = "id"
I am not familiar with the ":variable" way of defining routes, but you can take from my example the ability to set default controllers, modules, and actions, without the need to explicitly define them in the url.