JCR_SQL2 example in Javascript? - aem

I'm looking for some sample code using the AEM JCR_SQL2 API in server-side Javascript (NOT Java), i.e. code that starts with use(function() { ... }) and is loaded via data-sly-use=${...}.
All Google results are 100% Java based examples.
What I've already tried: Google "JCR-SQL2 js example" and variations.
Expected result: sample code in Javascript.
Actual result: lots of Java code :-(

If you wanna use server-side JS (what I don't recommend), then you only have to convert the syntax of the Java examples. You interact with the Java-Objects anyway. So the API is the same for JS as for Java. In case you have a HTL component and calling the JS via the Use-API, then several objects are already defined in your JS scope.
https://helpx.adobe.com/experience-manager/htl/using/global-objects.html
Here is an JS example to search all core components with a SQL-2 query:
use(function () {
var pageName = currentPage.name;
var title = currentPage.properties.get("jcr:title");
var resourceName = granite.resource.name;
var resourceTitle = properties.get("jcr:title");
var componentList = [];
var componentIter = resolver.findResources("SELECT * FROM [cq:Component] AS c WHERE ISDESCENDANTNODE(c, '/apps/core/wcm')", "JCR-SQL2");
while (componentIter.hasNext()) {
var compoenentRes = componentIter.next();
componentList.push(compoenentRes.getPath());
}
return {
pageName: pageName,
title: title,
resourceName: resourceName,
componentList: componentList
};
});
The component HTL code to use it, would be:
<div data-sly-use.info="info.js">
<p>page name: ${info.pageName}</p>
<p>title: ${info.title}</p>
<p>resourceName: ${info.resourceName}</p>
<p>core components: </p>
<ul data-sly-list.component="${info.componentList}">
<li>${component}
</ul>
</div>
PS: You probably know, but here you find the Use-API for JS:
https://helpx.adobe.com/experience-manager/htl/using/use-api-javascript.html

I'm not aware of any Web-API for JCR_SQL2 queries. You would have to implement your own Servlet in AEM (with Java), which would accept queries from external HTTP requests. Then you could call your servlet from your JS code via Ajax, and execute the query inside AEM with Java.
Maybe the Query Builder API is interesting for you. This query-language is already available from the outside, and can be called via Ajax. For testing and developing your queries you can use the Query Debugger:
Adobe Documentation:
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/querybuilder-api.html
Query Debugger:
http://localhost:4502/libs/cq/search/content/querydebug.html
Query Debuger with Sample Query:
http://localhost:4502/libs/cq/search/content/querydebug.html?charset=UTF-8&query=type%3Dcq%3APage%0D%0Aorderby%3D%40jcr%3Acontent%2Fcq%3AlastModified%0D%0Aorderby.sort%3Ddesc
Sample Query called directly:
http://localhost:4502/bin/querybuilder.json?orderby=%40jcr%3acontent%2fcq%3alastModified&orderby.sort=desc&type=cq%3aPage

Related

Javascript Routing in play Framework not working

I´m having a curious problem in my application when I use the Javascript Routing of Play Framework. This is the problem:
Screenshot
and this is my code:
class Application extends Controller {
import play.api.mvc._
import play.api.routing._
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(routes.javascript.ProcessController.retrieveAllProcess)
).as("text/javascript")
}
}
this is muy route file:
GET /javascriptRoutes controllers.Application.javascriptRoutes
GET /Process/All controllers.ProcessController.retrieveAllProcess
this is the html.scala file:
var option =
{ "url" : #routes.javascript.ProcessController.retrieveAllProcess,
...
}
Thank you so much :).
I think you're confusing the javascript routing with reverse routing.
Javascript routing
Javascript routing is meant to generate javascript code. The generated code defines functions that can be used in your javascript to generate urls at the client side. Since you've defined an Action returning the generated code, you could include it in your page by using
<script type="text/javascript" src="#routes.Application.retrieveAllProcess()"></script>
Note that this uses reverse routing to tell the html page which URL should be used for the script. :)
Then in your javascript code it can be used like so
var retrieveAllProcessRoute = jsRoutes.controllers.Application.retrieveAllProcess()
to generate a javascript object containing both the HTTP verb and url to the Application::retrieveAllProcess method.
Reverse routing
Reverse routing is used to generate scala code. This code is meant to generate URLs in views or Redirects to controller methods on the server side.
Since you're talking about a template (*.html.scala), you're talking about the server side of things. This means that you should use the reverse routing capabilities of Play. Below I've rewritten your javascript template snippet to use reverse routing:
var option = {
"url": #routes.Application.retrieveAllProcess,
...
}

How to create a website with a searchbar to query a mongo database?

I have a large mongoDB database set up and am trying to create a website where a user can use a searchbar to query the database remotely and have the results posted on the site (strictly read-only).
I have experience with databases for data analysis, but have never created a website for querying results.
I'm don't have any experience with web development and don't know what platforms (PHP? node.js?) to use.
Thanks in advance.
There are the following steps to the problem:
Create the front-end, which will consist of HTML, CSS, and Javascript. Beginners often find it easiest to work with jQuery and jQuery UI, because they are well-documented and contain plugins for almost all possible scenarios (they should not, however, be used to create large complex applications!). Bootstrap or Foundation can help you with the HTML / CSS.
Create a (probably) JSON API, which the front-end can communicate with to submit searches and retrieve results. You could use PHP, Python, Ruby, or many other languages to do this. For a simple site like the one you're describing, it's more a matter of preference than anything else.
Translate the search request from the front-end into the MongoDB query APIs, and return the results through the API. You will use a MongoDB client library compatible with whatever language you have chosen.
Depending on your needs, you may be able to eliminate (2) by using an existing REST API for MongoDB.
Note that if you just want to make MongoDB data accessible via searching / charting, then you may be able to avoid coding altogether by leveraging SlamData, an open source project I contribute to. SlamData lets you use Google-style search (or more advanced SQL) to query MongoDB and get the results back in tabular or chart form.
I am doing such in nodejs.
In my server side app I have connection via mognoose like:
var mongoose = require('mongoose');
mongoose.connect('mongodb://yourhost/database');
Next you need to have your model to your database
var YourDBVarName = mongoose.model('collectionName', {
yourfields1 : type,
yourfields2 : type,
yourfields3 : type
...
});
Then I make GET for it
var express = require('express');
var app = express();
app.get('/dblisting', function(req,res){
YourDBVarName.find({ yourfieldsX: 'value'}, function(err, data) {
if(err) {
res.send(err.message);
}
else{
res.send(data);
});
});
Then simply you make some GET with $.ajax to yournodeserver.com/dblisting and in response you recive your collection filtered as in
{ yourfieldsX: 'value'}
Ofcourse you may do just {} so you get all your stored data.
SLee
If you want know about retrieving data from mongoDB, you can use my github https://github.com/parthaindia/CustomMongo .Use getByCondition() method which requires collection name and a Map . The Map can be your queries in form of key value pair,Key being the column name. I use this method when I write search Query for the web development. The java code gives you a Json. Write a Servlet to post your Json to WEB UI.
This is an example to show how to post the retrieved data using Js ,"server_base_url + /server/FetchData" would be your Service URL.The data you has to be appended to a table . Or a span ,depends on what you actually want.The below code appends data
function getdata() {
$.get(server_base_url + "/server/FetchData", {
}).done(function (data) {
$.each(data, function (index, value) {
alert("The Index" + index + "The Value" + value);
$("#11table1").append("<tr><td id='dynamicid1" + index + "'>" + value + "</td></tr>");
});
});
}
This function can be used for defining table
function defineTable() {
$("#mainDivID").text("").append("<div id='contpanel' class='contentpanel'>");
$("#contpanel").append("<div id='rowid11' class='row'>");
$("#rowid11").text("").append("<div id='row11table1' class='col-md-12'>");
$("#row11table1").text("").append('<br /><br /><center><h5 class="lg-title mb5" style="background-color:#428BCA;height:20px;color:#fff;padding-top:4px;"><b>Heading</b></h5></center>');
$("#row11table1").append("<div id='table11id1' class='table-responsive'>");
$("#table11id1").append("<table id='11table1' class='table table table-bordered mb30' >");
$("#11table1").append("<thead><tr><th>Index</th><th>Value</th></tr></thead>");
}

How to inject data from db into jade template?

I am trying to import data from mongodb into jade template, in order to show them in graph. I am using chart.js inline script, in order to render data on graph. So data from Mongodb is on the page, and I can access it like this:
each city in cities
p #{city.name}
And here is how I pass data to page:
exports.index = function(req,res){
var cities = City.find({}).limit(20);
cities.exec(function(err,doc) {
res.render("index",{cities:doc});
});
};
I created same app with php, by simply passing data to page and injecting data into javascript graph(with json_encode)
Here is final result with php:
It was easy, since php data are global to HTML page. How to do that with Jade ?
Thanks
Ah, so your goal is to both use the city data to generate HTML on the server but ALSO make it available in the browser as raw javascript object data. To do that you format it as JSON and stuff it into a <script> tag. There are modules to help with this such as sharify,
but the basic idea in your jade template do something like:
In your express route handler javascript:
exports.index = function(req,res){
var cities = City.find({}).limit(20);
cities.exec(function(err,doc) {
//There are tricky rules about safely embedding JSON within HTML
//see http://stackoverflow.com/a/4180424/266795
var encodedCityData = 'window.cities = ' + JSON.stringify(cities)
.replace(/</g, '\\u003c')
.replace(/-->/g, '--\\>');
res.render("index",{cities:doc, encodedCityData: encodedCityData});
});
};
In your jade template:
script!= encodedCityData
In the browser, you will have access to the data via the cities variable which has been set onto the window object.

Data does not displayed correctly when using tokeninput with liferay portlet?

I am using token input to search data as follows:
<portlet:resourceURL var="categoryRequestURL" />
<script type="text/javascript">
$(document).ready(function () {
var catUrl = "<%=categoryRequestURL%>";
var cat_input_id = "<%=portletNamespace%>categories_selector";
$("#textbox_id").tokenInput(catUrl, {theme: "facebook"});
});
</script>
And in the public void serveResource():
PrintWriter writer = resourceResponse.getWriter();
JSONObject j1 = JSONFactoryUtil.createJSONObject();
j1.put("id", "1");
j1.put("name", "Data center");
JSONObject j2 = JSONFactoryUtil.createJSONObject();
j2.put("id", "2");
j2.put("name", "Database");
catJsonArray.put(j1);
catJsonArray.put(j2);
writer.write(jsonArray.toString().trim());
writer.flush();
writer.close();
The problem was whatever I entered in the input box, all data in the json array was displayed:
However, if I hard coded json data instead of using resource url. Then it worked correctly.
Does any one have any ideas?
I have no experience with liferay in the slightest, but think I can see what is 'theoretically' the problem.
With jquery tokeninput, when you use an external URL to get your search results, you must deal with the search logic yourself. This is to allow you to query databases and such like. The search parameter is (by default) sent to your page in the GET parameter 'q', and the JSON you return should only be the relevant search results, rather than the entire collection of data.
As I say, I have no idea how to implement such a thing using liferay - but from looking at your code, there doesn't seem to be any point where that logic could be in there!

from javascript to jinja2

Is it possible to access data obtained via .getJSON call in jquery as a jinja2 variable ?
$.getJSON(
$SCRIPT_ROOT +"/gitem/"+node.id,
function(data){
if (data.length > 0){
$.each(data, function(index,val_dict) {
var button_id = "button_"+String(index);
var popup_id = "element_to_pop_up_"+String(index);
var append_string = sprintf('<div class="icony"><img src="%s" height="75" id="%s" >%s</div>',val_dict.img_url,button_id,val_dict.img_caption);
var bpopup_element = sprintf('<div id="%s"><a class="bClose"><img src="%s" width="500px">X<a/></div>',popup_id,val_dict.img_url)
$('.data_area').append(append_string+bpopup_element);
$('#'+popup_id).hide();
$('#'+button_id).bind('click', function(e) {
e.preventDefault();
$('#'+popup_id).bPopup();
});
});
}
else
{
var append_string = '<div class="icony">No Images to display for this category</div>';
$('.data_area').append(append_string);
}
$("#list_viewer").css("display", "block");
});
For example in the above I am getting the data and then constructing the DOM within js. While what would be best would be to import data via .getJSON and then set the data as a jinja2 variable.
Later I can use that variable within jinja2 template ?
it that possible ?
or better still...
can a jinja macro be called from within the .getJSON function ? that can also allow embedding of json data within jinja2....
thanks for any pointer...
Probably not. Jinja generally runs on the server, rendering your web site templates before sending them off to the client. The client (i.e. your web browser) will not have access to the templates.
If you'd like to use Jinja templates to render client-side JSON objects, you could take a look at Jasinja, which is a tool to convert your Jinja templates to JavaScript, which you can then use in the browser. A number of similar tools exist.
Finally, another solution is to send your JSON data to the web server, render them to HTML via Jinja, then send back the resulting HTML in the XMLHttpRequest response. However, if you've obtained this JSON data from the same server you use to render templates, you might be better off just having HTML sent to the client directly and added to the DOM from there.