Pages

Wednesday, May 31, 2017

Bye bye classic interface

"Adobe is planning to deprecate the Classic UI in AEM in April 2018. The 2018 release of AEM will still contain the Classic UI as it is part of current AEM release. Following that, Adobe is planning to remove the Classic UI from AEM in April 2019.”


A very quiet and unceremonious announcement on what we all knew was coming. Now we have a date.

It's more important than ever to move to the Touch operating model, and to modernize all components.

Tuesday, October 18, 2016

Adobe has rebranded Sightly

If you hear the term HTML Templating Language, or HTL, this is the new name for Sightly.

Nothing has changed in the language, nor has the philosophy or direction that the Adobe team are taking.

Saturday, February 27, 2016

Bringing a Human Experience to Software

Today, I'm sitting in the Singapore Airlines lounge at Changi airport, and I am compelled to share a story with you. I have been working for a bank for the past two years, charged with the responsibility of enabling and empowering the business with Adobe Experience Manager across the global enterprise.

I have just returned from a week with our hub in India, and a stark observation has been haunting me for my entire plane flight. For a piece of software entitled Experience Manager, when we implement, we rarely Manage to Experience.

AEM was and is currently in my opinion the right choice of platform due to its flexibility and configurability. Most implementations I have seen produce beautiful and engaging experiences to the customer, but we so often fail to tell our story well to the most important users within the system, the author.


The author is the writer of the story, but we are disempowering them with a bad experience
I am a big fan of Charles Bukowski. In his book, Postman: http://www.goodreads.com/book/show/51504.Post_Office

Bukowski has many brilliant truths, but none strike more to me than his take on technology transforming how an author writes. He talks about how cumbersome it was to write on a typewriter. It was hard to write, as the keys were difficult to press, his ideas were constrained to be linear, as he couldn't go back a paragraph to insert a new idea into something he had written, or to enrich and improve a sentence. It was like trudging through the mud, cumbersome, tiring, making you focus on what you were doing, rather than on what you were saying.

To him, the word processor changed his writing, as he could move freely through his prose, changing and nudging his words, moulding and shaping them freely without hindrance. It was no longer like trudging through the mud, but rather like ice skating. He could freely glide with grace, circling and gliding through his thoughts, carving out a reality from nothing to a complete and vivid suspension of disbelief. It empowered him to tell his story.

People learn by stories... Tell me your story

Last year whilst on holiday in the States visiting my inlaws, I met a man who completely challenged my world. His name is Peter Balwyn. I remember sitting around a large spread of food around the table, the extended family from all parts of the states and the world had converged to see my two young children, my wife and myself.

Surreptitiously, I had mentioned another man who had changed my life, Viktor Frankl. I spoke of his book, Man's search for meaning.

Man's Search for Meaning - Streetschool


His theories were the antipodean of what I had understood to be Abraham Maslow's base needs heirarchy.



Maslow's thinking and theory to my understanding was so practical, so logical, so straightforward. 


When I was studying Artificial Intelligence and Machine Learning at university over a decade ago, I first heard of Maslow and understood his theory to be that humans were driven to fulfill their needs from the bottom up. If they were dropped naked in the jungle, they would need to find food and water first, then shelter and safety. They would need to have some sort of social interaction, be that another human, a pet or a sock puppet and finally to fulfill their self worth and self esteem before they can self actualise.

Only once your house built with a river running through it, a garden bed to grow your vegetables, a few pigs and cattle, and you could sit down with your friends behind your electric fence on a deck chair with your shotgun in one hand, and a martini glass in the other could you think about life, the universe and everything.

Frankl's idea was born in the most harsh of crucibles of the 20th century, Auschwitz and Dachau. The first half of his book tells his story of how he came up with his revolutionary thinking, and how it empowered him to survive the camps, the second half dove into deep psychological theory.

He survived not by fulfilling his physiological needs, safety, social fullfillment or esteem, as obviously the camps were specifically designed to erode and crush every soul that entered to dust, but rather his own higher purpose. To shape, define and tell his theory to the world.

He observed those that lived and those that perished, and the differentiator in those that lived, is that they had a lighthouse to swim to. It was the hope of seeing their children, their wives, their parents. Often when the strongest who had held onto their family as their hope had discovered their loved ones had been extinguished, the light of their hope became a dark barren pit of despair, and lost, they were overcome and consumed by the machine.

Peter rebooted my thinking, as it turns out Frankl was his supervisor, and he also knew Maslow personally, and as it happens, I had not understood Maslow's story correctly.

If I were dropped out of a plane into the ocean and told the nearest land was a thousand miles away, I'd still swim. And I'd despise the one who gave up.- Abraham Maslow
Hope, higher purpose, inspiration was the raw stuff of empowerment.

Peter showed me by example in one day how playfulness and stories can burn memories instantaneously into one's ken. He had an aura about him that was infectious with energy, hope, grand visions, grand dreams and deep thoughts. Most of all, he made everyone feel safe. He never said no, or that you are wrong, always using positives to highlight gaps and inconsistencies in a safe, judgement free way.

He taught me on so many levels through his stories, so stark, so simple, elegant and easy to understand, he changed my story forever. I still think back to our conversations and glean something new every now and again. All in a story's time to learn, and seemingly a lifetime to master.

He pressed his book, gleanings, into my hands and asked if I would read it. I did.

http://www.selfpublishingpress.com/content/Peter%20Baldwin

I feel that us technical types are great at instructing machines. We tell them what to do, we give precise instructions, conditions and model everything mathematically with cold precision.

Humans don't work that way. We need to be inspired. We don't like being told what to do, we don't like being led, read dragged, to the right answer. The great leaders don't lead at all, but inspire and empower through their stories. Amazing leaders make you invincible.


And thus I come to what has been bothering me. So often in our implementations of this fine product known as AEM, we forget what the cornerstone of an amazing CMS actually is all about empowering the author to tell their story.

We allow technology to get in the road of their thinking by allowing the Skeuomorphisms of previous implementations to bleed into the next generation. How often have you seen business requirements that demand that we make AEM act like IBM WCM, Fatwire, Vingette or OpenText. I understand completely that sometimes you want to put the cart in front of the horse because you don't want to smell the horse, but from a design perspective this is committing the same error as trying to make glass like wood or metal in construction design.

We build beautiful customer experiences, and we disempower the author entirely.

We build systems that suit the thinking of developers, not the thinking of the author.

Let me share a story with you. When I first started with the bank 2 years ago, I was given a case from my boss, where a vendor was building a system for a division of the bank, and the division was not happy with what was being produced. Costs were huge, flexibility was low, and every time they wanted to make a change they had to re-engage the vendor.

I sat with the authors, and immediately I noticed what was happening. There were over 120 components in the system. This was a simple web page. How can there be 120 separate components?

In a nutshell, here are the examples of the components:

  1. Image on the right, text on the left.
  2. Image on the left, text on the right.
  3. Image on the right, text on the left, radio buttons underneath
  4. Image on the right, text on the left, checkboxes underneath
  5. Image on the left, text on the right, checkboxes underneath
  6. ....

Notice that Image on the left, text on the right, radio buttons underneath was somehow missed. I was to raise a Statement of Work with the vendor on behalf of the business unit to add this component.

At this point, I pulled up stumps and demanded a reboot. This was crazy. The authors didn't know what to do. They were swarmed with 120 and counting components, not all components worked in all places. Call to Action components which were essentially an image with a button that linked off to another page. The problem was that this component couldn't be used everywhere, only within one particular parsys that was hard welded onto a particular area of the template. It went entirely against the axiom that AEM is a box of Lego's that the author can piece together to make whatever they want.

I took charge of the project and we delivered what we could with the limited remaining budget. We couldn't entirely solve the problem, but we greatly simplified the authoring interface, pushing back on the minor and unimportant requirements that demanded a bespoke component be built for everything.

Today, we are working on a common components toolkit that brings polymorphism to components, and the ability to paint with a simplified pallet.

I will know when we are a success when our authors can paint masterpieces with the simplest of primary colours in our component pallet, the core lego set, the atomic components, layout and content:
Column Container
Grid
Image
Text
Video
Download
etc.

But how can we achieve custom functionality with so few components? When you drag an image onto the screen from the sidekick, you can refine the kind of component it is. An image can be a standard image, an adaptive image, a call to action, a hero, a header, whatever you want it to be.

The dialogues are modeled in such a way that they transfer between each other, an image source is still an image source, no matter whether its a call to action, a hero banner or a header. It allows the author to ice skate around what they are doing. To change their mind, to alter what the image is saying and doing, without having them be distracted by deleting the component and retyping. Not to mention the cardinal sin of AEM, hard welding components onto a template. It is a template, not a prescribed method of operation.

Furthermore, every component must be liquid in itself, stretching and shrinking to adapt to its parent container. This not only solves the "not in my parsys" problem, but also aids with responsive design, as the flexibility of the component on a mobile device is now no longer limited to its gridspan settings.

Each of the dialogs are modelled in SlingModels, and given a version number. When we change the structure of a dialog, it breaks content. This is not acceptable. All content needs to be forward transformable. As in, we take the Sling Model in the particular version number, and we transform it to the new version dynamically, both in a big bang format by running a script to search for versions of data within the JCR that correspond to that model and need uplift, as well as intercepting the event when a dialogue loads, upgrading the version of the data to that of the component dialog with our Sling Model persistence extension.

We must both allow the author to lead and to follow. When a new user gets into the system, there needs to be enough to suggest what they do next. There is quite a bit still left to do in the touch interface to achieve this without at least some basic training, but we should not be compounding the issue. Our components should easily tell their own story, to allow our authors to syncopate and ice skate through their thoughts. The technology must get out of the road.

We also cannot forget that the experienced author will want to lead us, to command and imbue their thoughts succinctly with the least amount of effort. To be able to change their mind at a whim, to be empowered, to feel like a god able to walk on water and part the waves with a single gesticulation.

Remember, you can always have your cake and eat it. Just buy two cakes.

We also can never forget, we are here to empower our authors to write their story. The true value of a CMS is its content, not the ability to rejig the rejiggulator.

Developers and designers need to keep in mind that the major actor in this system is not robotic, but human, and we must interact in a minimalistic way to get technology out of the road, to allow the author to be the genius, to tell their story in a transparent and elegant way. To allow their ideas to grow and flourish without being perverted by needless system constraints and ham fisted interfaces.

We are evolving the way we interact with our technology, and I am excited to see what the next evolution of AEM will bring in the integration space.

In the words of God in Futurama Series 3, Episode 20 - Godfellas:
When you do things right, people won't be sure that you've done anything at all.

Tuesday, July 22, 2014

CQ5/AEM Gotchya - When trying to fake a post request, you get the following error in the logs:

The Problem

POST /my/post/url HTTP/1.1] org.apache.sling.security.impl.ReferrerFilter Rejected empty referrer header for POST request to /my/post/url

The Solution

The problem here is that you are not correctly spoofing the Referer address. To avoid this problem when testing, you can disable Referer filter checking by going to localhost:/4502/system/console/components, go to Apache Sling Referrer Filter, and check the "Allow Empty" checkbox.

This will disable the referrer security check in CQ5 for your developer instance.

NOTE: DO NOT DO THIS FOR PUBLICLY ACCESSIBLE CQ5/AEM INSTANCES AS IT POSES A SECURITY RISK

Wednesday, July 9, 2014

How to find the version number of CQ or AEM that you are running

Go to http://<author>:<port>/system/console/status-productinfo

And you can see the exact version and build number that has been installed.

Installed Products
  Adobe Experience Manager <versionNumber>

Tuesday, June 17, 2014

How to programatically design mode select a component to be included in the sidekick

The Problem

You want to have a component programatically available to authors without having to enter design mode and add a component for the template.

The Solution

Go to your relevant template's design mode. For this example, we will use the Geometrixx site, located at:

/etc/designs/geometrixx/jcr:content/contentpage/par

Then edit the components property to contain the path to your component, for example:
/apps/geometrixx/components/customcomponent

Save, and reload the editor, and you should have the component added to your list.


Friday, May 2, 2014

CQ5/AEM How do I detect from a SlingServlet whether it is running on the Master or Slave instance on an author cluster?

The Problem

You have a Sling Servlet performing a task on the author instance, and you are running as a cluster. The code is executing on both the master author and the slave author instance, when it should only be running on one.

How do you detect whether the instance is the master instance?

The Solution


@Reference
private SlingRepository repository;

public boolean isMasterRepository(){
    final String isMaster = repository.getDescriptor("crx.cluster.master");
    return StringUtils.isNotBlank(isMaster) && Boolean.parseBoolean(isMaster);
}

With this code, we can detect whether the current instance is running as the master.

In the execution function, the first conditional should be to detect whether it is running as the master instance or not, and if it is not, it should terminate the function call.