Friday, March 4, 2011

Displaying json for cq:Page components in Day's JCR

I can't believe I didn't realize this sooner. But here is a brief explanation.

Every time I would go to a cq:Page in the JCR and ask for it's json rendition I would only get the json for the cq:Page node.

So asking for http://localhost:4502/content/somePage.json gets your this response:

{"jcr:createdBy":"admin","jcr:created":"Tue Mar 01 2011 19:33:03 GMT-0700","jcr:primaryType":"cq:Page"}
Well the TidyJsonServlet is what is getting called here and it needs a selector to keep recursing down into the page.

So you need to do THIS request instead http://localhost:4502/content/somePage.infinity.json
That will give you the json for the jcr:content node, the bodyContent parsys, and everything underneath that as well. Other selectors you can use are 1, 2, and 3. I think those are the only one's supported in addition to 'infinity'.

FYI!


Using vault from IntelliJ


This post is for any Jcr/CRX developers out there that are using IntelliJ as their IDE instead of CrxDE.

Ok, the reason I'm writing this little post is that I see several developers at my company using IntelliJ for developing against the Day server, but they keep a separate Terminal window open for doing all of their Vault commands. If you don't know what vault is or does, then this article is probably not for you. But if you do...

There is a feature in IntelliJ called External Tools. With it, you can make IntelliJ call, you guessed it, an external command. For our purposes we want to configure it to call a vault command, so that we don't have to keep a separate window open to add/update/checkin new files into the Jcr. In the screenshot above you can see my current External Commands vault setup.

Lets look at the 1st configuration, the checkin.



So on this screenshot you can see that I've named the command "vlt ci", and that I've put it in a Group called vault. This will group all of the vault commands together in your right click menu.

Also, in the Program setting I've pointed to the external program, the vlt command. On my system it is located in ~/apps/day/author/crx-quickstart/opt/filevault/vault-cli-2.2.22/bin/vlt.

The parameters setting gets ci $FilePath$ --force. I always do force, don't ask me why it just seems to work better.

And the last setting, Working Directory, gets $FileDir$/..This will allow you to right click on any file in the Project view tab or just right click on an file you have open, and the vault command will execute as if you had run it in that directory.

A quick note about the Parameters & Working Directory:
The reason I do: ci $FilePath$ --force is that the $FilePath$ will put the full filepath in the argument, and in the working directory you always want to be one directory up from where you are working. The reason to do this, is that you want to be able to use the same command for both files and directories.

If you click on Insert Macro right by that field you will see some of the different options you can use.

So with this information you can create, Status, Delete, Update, and Add the same way. (Status won't need the extra stuff in Parameters, just the 'st' command.

After that I add my keymappings to do these quickly. I like Alt-C -> checkin, Alt-X -> status, Alt-A -> add, and Alt-Z for delete.


OUTDATED: (The 2 separate commands 'below in grey' should no longer be needed if you do it the way I specified above)
One final little hack for the Add command. I had to create 2 separate commands - one for adding a directory, and another for adding a file. The only difference for adding a directory was that I had to move up a directory in the Working Directory field. Here is the screenshot that shows this:



And now you are setup. When you create a new file that you want to insert into the Jcr, you simply right click on it, and now in your right click menu, you should have a section named "Vault" that you can browse into and see a command names "vlt add file". After that you can check the file in in the same way.

If you run into issues, the console output at the bottom of your IntelliJ should give you some hints as to what you might have done wrong.

A couple of reasons why you want to do this from IntelliJ
  1. You don't want to keep a terminal open and pointed at the jcr_root directory of your project. On my projects I actually have several src root directories so if I'm using Terminals to vault stuff I actually need several Terminals open, each pointing to the src root so I can vault things up.
  2. Speed: Doing a whole tree checkin from the src root each time is slow. It's much faster to check in a file from the working directory. e.g. A file is in jcr_root/apps/stuff/stuff1/stuff2/stuff3/file.jsp. If you check it in from the jcr_root directory this can sometimes take several seconds (like 15 seconds sometimes on my system). If you cd down to the stuff3 directory and do a vlt ci there, it will work very quickly.

Hope this helps!


Wednesday, March 2, 2011

Mashable web applications

Mashing up your applications

Keeping web applications separate but mashable is an interesting problem we've tried to solve here at my company.

I'm going to post the 3 ways we've tried to approach this, and hopefully I'll get some feedback.
So this is our setup (I'm keeping it simple). Here are our applications that we want to "mash up":

  • The signup app
  • The shopping app
  • All other "parent" web sites
A brief explanation of these 3 applications:
The signup app - You must signup before you can buy our products. The signup application basically just presents the users with a form that gathers their information, a verify screen, and a success screen. From the success screen the user can select a couple of options, whether they want to go on to buy normal products OR whether they want to setup a monthly recurring order.

whichever choice you pick sends you to:
The shopping app - This application handles buying products. It simply has a "cart" page, on which you can do an ajax search and add/remove products in your cart, a Payment/Shipping page in which you decide how to pay and where you want it to go, and finally a success page where you get an order number.

At our company we decided that we wanted to write these 2 applications one time, and then reuse them over and over again in different contexts or consuming applications. So we made both applications "skinnable" by allowing you to initialize them with different css skins.

3 approaches used:

1. Iframes

This was our inital approach. This allowed a "parent" application to embed the signup or shop apps wherever they wanted.

So the parent application had a page like https://www.parent.com/shopping.html
which included an iframe that pointed at https://www.parent/com/shopApp?

The parent app was one web application deployable, and the shopApp was another web application deployable.

This approached defined a lot of interface points such as:
  • "landing pages" that the signup/shop apps would redirect back to once the user was done with an operation such as "signup" or "buy products".
  • Css initialization, various parent applications wanted the embedded shop/signup apps to use a different color scheme that meshed better with their look.
  • initialization parameters - for both signup and shop apps we initialized those applications with parameters like "calling parent application id", products skus, or startup modes.
PROS: The shop & signup apps looked very embedded on the "parent" apps what used them.
CONS: The shop & signup apps needed to be on the same domain as the calling applications to facilitate things like iframe resizing, and cookie sharing. Domain profileration: basically we needed to purchase a secure domain for every parent app that wanted to embed shopping or signup. At our company we had at least 10+ domains and growing that wanted embedded shopping and signup.

2. Redirects
This was our 2nd approach. Basically we decided that we wanted the shop & signup apps to have their own domain and we didn't want to buy a new secure domain every time we wanted to launch a new site.
So now the parent application http://www.parent.com redirects to https://shop.parent.com.

Again the http://www.parent.com is one web application and https://shop.parent.com is another web application.

Again, interface points are required to pass between the applications such as:
https://shop.parent.com?landingPage=http://www.parent.com/doneWithOrder.html

The CON and PRO with this approach is that the shopping application is now more decoupled from the look or the parent application. One approach used to mitigate this is by using apache server side includes to include a header and footer on the child application.

i.e.
[ header ssi ]
[ main content ]
[ footer ssi ]

Where the header & footer ssi is a header that is produced by the parent application.
The advantage of this is that, if the parent application changes the look of their header or footer, the signup or shop applications do not have to be redeployed - just the parent application needs to change.

3. Pure ajax application
The last approach we are considering, is converting the signup/shop applications into pure ajax applications. This should allow for the applications again to be mashed into the parent application at any point without having to redirect.

Again, each child application basically has 3 "views".
- The signup application has: "fill out form", "verify form data", and "confirm signup".
- The shopping application has: "show cart (where you can add/remove products)", "choose payment/shipping", and "order confirmation"

To produce a "pure ajax" application, each child application (the signup & shop applications) would produce 3 elements or "views" that are hidden or shown depending on the user interaction. The views are controlled via javascript as well as are the calls back to the server such as:
"create order", "signup", "validate field", etc...

All server side interaction is done via restful web service calls.

The "parent" application pulls down the html via a javascript include.
i.e. To embed the pure ajax application it could look like this:



<script src="http://www.shop.com/shop?containerId=shopContainer"></script>
<div id="shopContainer"></div>


The javascript file loaded would automatically load the shopping application's html into the #shopContainer div. All of the other controls needed for the shopping application are loaded in the javascript file.

Note: for my purposes, the the shop.js resource is actually a java servlet that produces all of the javascript code. Of course this resource can be anything that produces the javascript.

PROS: No need for iframe resize callbacks. Everything is on the same domain, including cookies. No need to pass css initalizers since the html pulled down via ajax will get the same css applied to it.
CONS: Most big companies seem to opt for option #2, Redirects. This allows for one shopping domain and one signup domain.


Your comments on these 3 approaches are welcome.

Tuesday, March 3, 2009

Using Maven for builds

Well, several months after doing an overview here at the company about maven, I finally decided to try and learn it.