Quantcast
Channel: Dan Klco – Perficient Blogs
Viewing all 49 articles
Browse latest View live

Migrating AEM Content with Groovy

$
0
0

Migrating content into AEM is nobody’s idea if fun. Creating experiences and authoring content in the powerful AEM authoring experience is great, but identifying, classifying and mapping legacy content? Not so much.

AEM’s repository structure contributes to this challenge. AEM, being based on the Java Content Repository (JCR) offers a massively more flexible content taxonomy than relational-based repositories, however, paraphrasing Uncle Ben, “with great flexibility, comes great mapping efforts”

Web content generally doesn’t deal with massive volumes of content, if your web CMS is the system is record for large amounts of structured content, you should have a discussion about what is the most appropriate system of record. The combination is the complex structure and relatively small volume makes traditional ETL tools such as Pentaho, Kapow or Apache Nifi a poor fit for migrating content to AEM as they are designed for high volume, predictable data.

Wouldn’t it be nice if there were a tool that made it easy to map legacy content into AEM with a simple, flexible and concise templating language? That would be

 

Austin Powers thinks it's Groovy, Baby Yeah!

 

I’ve been working on a migration script which is exactly that. The script allows migration developers to define flexible mappings to convert legacy content to AEM pages and components. From there, the migration team uses CSV spreadsheets to manage how content is migrated. The script is designed for Web content migraine and is best utilized for migrating moderate amounts of content which can be exported as XML.

Not surprisingly, the script is written in Groovy and uses Groovy for the transformation of legacy content to AEM. I’ve provided a .commons.groovy file to handle some of the more common mappings such as setting page properties, handling the JCR Namespaces and creating a simple component.

 

Using the Migration Script

 

Using the Migration Script is fairly straight forward. I’ve written a quickstart guide to using the script and have recorded a video to walk through using the AEM Migration tool:

 

 

Getting Started

 

The AEM Migration Script is available free on the Perficient Digital GitHub and can be extended and used under the GPLv3 license.

 

The post Migrating AEM Content with Groovy appeared first on Perficient Digital.


4 Steps for Personal and Digital Marketing Fitness

$
0
0

As Digital Marketers we are bloated with options for tools and processes and have bloated backsides from sitting at desks all day long. Over the past 3 years I have lost and kept off 80 lbs and have led multiple end-to-end digital marketing transformations. I can safely say I’m a bit of an authority on both personal and digital marketing fitness.

In both our personal lives and careers, being fit allows us to do more with less, be more agile and frankly just be happier. I have found there are five keys steps to being both personally fit and fit in digital marketing.

  • Have short term goals and long term vision
  • Get the right information at the right time
  • Remember it’s a journey not a destination
  • Have a system

Enough pebbles make a mountain

Short Term Goals, Long Term Vision

80lbs of weight loss is, to say the least, intimidating. However, with just a few changes, nearly anyone could lose 5lbs, right? Then 5lbs again and again. Small, achievable goals bring momentum and combine together to revolutionary change.

Having a vision is important, but even more critical is breaking the vision down into small achievable steps. These steps can be as small as losing 5 lbs, improving a particular customer interaction or improving a single campaign.

These small goals must align back to the larger vision and must be measurable and attributable to the desired outcome.

Splits Graph

The Right Information at the Right Time

As I left downtown, my music dimmed and I listened intently to my pace for the last 1/2 mile split. Up ahead, I could see the path snake back upon itself as the course climbed over 300 feet from the river valley of the Ohio river to the peak of the hills surrounding Cincinnati in Eden Park. The next mile would make or break my goal for this running of the Flying Pig Half Marathon.

Having this wealth of information at my fingertips makes me a better runner as I can compare to how I expect to be doing and adjust my pace to respond. Running a bit too fast? I can pull back, running a bit behind pace? Time to pick it up!

As marketers, we need data in real time and we need to tie this data to actionable KPIs. A single split time doesn’t make a race, just as much as a single Ad doesn’t make a campaign, but understanding the trend and being able to respond in real time enables us to avoid missing our goals.

Similarly, in my personal fitness, I’ve found tracking my weight on a daily basis enables me to predict the trend and keep myself on target.

We need to have the data frequently enough to develop the trend, but not drown in irrelevant information. At the same time, you can’t expect progress every minute and every day, consistent progress over time is key.

Fitness is a Journey

A Journey not a Destination

One of the hardest things about losing weight is accepting that you can’t go back. You can’t eat the things you did before, do (or not do) the things you did before or you will end up in the same place. You will always have to at least think about calories and do some level of exercise or eventually, the pounds will catch you back up.

At the same time, knowing fitness is a journey is liberating. Just this month, I have made two personal records, running a half marathon in 1:51:39 and a 5K in 0:24:07. Now, I want to see if I can get under 1:45 and 0:24 the next time around.

It’s the same in digital marketing. A single project doesn’t make your marketing a success, neglected maintenance will come back to haunt you and every customer’s best interaction is now the bar they use to judge every brand interaction. After our success, we cannot sit on our laurels, we need to pick up and move the goalposts.

By thinking about the journey, not the destination, you will be better mentally prepared to be fit. Additionally, there’s no small pleasure in knowing that around every curve there’s a new obstacle to overcome and there’s always another mountain to climb.

Dials

Have a System

Collecting data and having goals is well and good, but how do you ensure you’re making progress? Physical fitness is largely a matter of will power, but having a good system can help put a finger on the scale.

I use MyFitnessPal to track calories and help keep my own worst inclinations in line. I’ve found that even when I go over, entering my calories into MyFitnessPal helps me keep an overage from spilling into a complete splurge.

Similarly, in digital marketing, having a solid governance plan and supporting tools ensures not only are you measuring progress, but that you are staying on track.

Overview

Being physically fit and being fit in your digital marketing requires determination, willpower and the right support. Contact us at Perficient Digital to learn how we can help you on your journey to Digital Marketing fitness.

Do you have a trick you use to be physically fit or be fit in your Digital Marketing? Leave a comment!

The post 4 Steps for Personal and Digital Marketing Fitness appeared first on Perficient Digital.

New ACS AEM Commons Contribution: Tag Reports

$
0
0

Tags are one of the most powerful features of Adobe Experience Manager (AEM), using tags content authors and asset managers can create secondary taxonomy associations between content.

The challenge with many AEM installations is that tag taxonomies tend to grow over time, especially if ad-hoc tags are enabled. AEM’s Tag Administration console allows Taxonomy Managers to delete, merge and move tags, however, before making changes, you really should understand how a tag is used. You can view references, but this is only available at the individual tag level.

Recently, I built a new Managed Controlled Process to create a report of the tags and their references. 

Starting the Tag Report Managed Controlled Process

Using Tag Reports

This report allows for configuring the following settings:

  • Tag Path – the path under which to search for tags. This will work for both /etc/tags and /content/cq:tags
  • Root Search Path – the path under which to search for references
  • Include References – whether or not to include the actual reference values in the report
  • Reference Method – this option allows you to select between using TagManager.find  which is faster, but will only search for cq:tags attributes under cq:Taggable nodes or a deeper search which does a full text search against the tag ID

Starting the report will execute the process in the background. While the report executes, you can open a summary of the report execution.

Tag Report Summary

Once the process completes, you can view a report with all of the tags under the path including:

  • Reference Count – the number of times the tag is referenced under the specified content tree
  • References – the list of references if Include References is checked
  • Status – the status of attempting to report the tag, generally should be Success
  • Tag Id – the AEM Tag ID for the tag
  • Tag Title – the tag title in English

The report can be viewed online or downloaded to an Excel file.

View the Tag Report

Getting Tag Reports

The Tag Report MCP will be available in the upcoming release of ACS AEM Commons. Check back soon to see when it’s released!

The post New ACS AEM Commons Contribution: Tag Reports appeared first on Perficient Digital.

An Outsider’s Recommendations for Adobe Managed Services

$
0
0

 

I’ll start this by saying imagination is easy, execution is difficult. Having worked with and observed Adobe Managed Services (AMS), it’s pretty clear that Adobe has a particular customer need in mind. Based on my experience, I’ve brainstormed a few recommendations for Adobe Managed Services that would help meet the needs of all customers.

Adobe’s customers vary widely in their maturity and goals. A one size fits all solution, as presented by AMS, does not fit every customer need. Especially for customers on the far ends of the maturity curve.

For less mature customers, AMS provides application-level support but does not provide the technical guidance an inexperienced customer needs to be productive with the Adobe Experience Cloud. Instead, customers are expected to have deep technical proficiency with the tools. This is a challenge without a partner engaged or internal subject matter experts.

On the other end of the spectrum, customers experienced with Continuous Integration and Delivery (CI/CD) are stymied by the limited CI options and infrastructure management provided by AMS solution and Cloud Manager.

For many customers, AEM is one part of a larger digital experience platform. Thus, having a proprietary deployment stack outside of the company’s control is not a desirable solution.

I propose making the following three changes to better serve all of Adobe’s customers:

  1. Introduce refined offerings to serve the different levels of customer maturity (more on this later)
  2. Refocus the goal of Cloud Manager from code deployment to platform management and align it to the customer maturity levels
  3. Institute AMS as a single point of support for the customer’s Adobe Experience Cloud products (e.g. Analytics, Target, Campaign, etc)

 

Leaves Changing Colors

 

New Offerings

Instead of the current static approach, three tiers based on customer maturity and goals would provide the right solution for almost any customer need.

Tier 1: Adobe Experience Turnkey

At the lower end of the maturity curve and well suited for mid-market customers, Adobe Experience Turnkey would be a limited, but quick to market and easy to support solution for customers without extensive IT support. This offering would be templatized and would allow a customer to deploy AEM without ever having to think about servers. Instead, AMS would handle all infrastructure, maintenance and deployments.

Similar to Brand Portal, customers would not be able to customize many features of AEM but can manage their content. For Adobe to support this solution would require the development of tooling for the configuration of the AEM Dispatcher and horizontal scaling mechanisms. However, would be an enormous boon to customer speed to market and reducing maintenance effort.

Since the customer need not be concerned with servers, charging for AEM with a server-based model would not make sense. Instead, moving to a usage-based model would allow AMS to scale infrastructure to meet customer needs while providing a cost-effective solution for the customer.

Tier 2: Adobe Experience PaaS

Adobe Experience PaaS would provide a best of both worlds’ scenario for customers with an existing IT infrastructure, but not looking to take on the complexity of managing an AEM installation or the associated infrastructure. Similar to Adobe Experience Turnkey, Adobe Experience PaaS would be templatized at the server level and customers would have limited options in customizing the low-level infrastructure. However, customers would have much more extensive options to customize their applications.

In Adobe Experience PaaS, the customer could use their own CI tools. Cloud Manager would be used for deploying infrastructure and build artifacts. But, unlike the current iteration of Cloud Manager, it would not perform the builds. Instead, Cloud Manager would have a RESTful API for the customer’s CI tool to post the deployment artifacts. Cloud Manager would then deploy the artifacts with a Blue/Green pipeline to ensure zero downtime.

Since customers are in control of the instances with Adobe Experience PaaS, pricing would be based on a combination of instance hours and traffic. The pricing should be above the individual server level, instead, thinking of AEM instances or environments as units.

Tier 3: Adobe Experience Advanced

Some organizations want to be in the cloud, but own their own destiny. For these organizations, having the AEM infrastructure hosted by Adobe is preferred, but they need server level access. This, of course, comes with some limitations, as they would not have the uptime SLA’s from AMS, but AMS would still provide support on a response time SLA.

Customers with Adobe Experience Advanced would have full access to do what they wish within their AEM environment including deployments, updates, integrations and customizations. This would be similar to the current AMS offering, with the added benefit and responsibility of full production access.

Unlike the other two options, Adobe Experience Advanced would be priced similar to the current AMS offerings on a software plus server basis.

A SpaceX Rocket taking off

 

Cloud Manager

Cloud Manager suffers from the same problems as AMS, by trying to serve everyone it misses many customer needs.

 

Challenging Customer Needs

I have had a chance to (attempt to) use Cloud Manager on a project as well as attending webinars presented by Adobe on Cloud Manager. Based on what I’ve seen, there are potential challenges for customers attempting to use Cloud Manager:

Single Repository Support

Cloud Manager only supports a single code repository for staging deployments. This will be a challenge for customers with a multi-tenant setup or who have created an Application Ecosystem project structure. This can be worked around by simply deploying built artifacts to Cloud Manager, but defeats the purpose and value of the tool. It also does not easily adopt to existing customers repository models and thus more sophisticated customers may be reticent to event purchase AMS because of this limitation.

Black Box

Unlike customer hosted or most cloud CI tools, Cloud Manager operates as a black box. While it will report on expected problems, based on previous project experience, it will not report unexpected problems, leaving implementation teams with no real recourse to diagnose the deployment issues.

Lack of Customizability

Most moderately mature implementation teams already have some preferred CI tooling, Cloud Manager doesn’t integrate with these in a meaningful way and duplicates functionality already available in Jenkins, GitLab or CircleCI. As with diagnosing issues, Cloud Manager does not allow extensive customization, of the build process or validation include static code analysis.

Aligning Cloud Manager to Customer Needs

 

Cloud Manager is problematic for moderately and advanced Adobe customers. Conversely, for Turnkey customers, having constraints and basic CI tooling would be beneficial.

For Turnkey customers, Cloud Manager would provide build and deployment services. Additionally, it could be the single source of truth for their Adobe Managed Cloud deployment.

Since moderately experienced and advanced customers already have CI tools, Cloud Manager’s role would be more limited. For PaaS customers, Cloud Manager would enable deploying (but not building) code as well as managing environments. And for Advanced customers, Cloud Manager would primarily manage environments.

By scaling the capabilities of Cloud Manager along with the customer’s capabilities, Adobe will best serve every type of customer with a solution that augments rather than hindering their process.

A waiter bringing drinks

 

Single Source of Support

With the breadth of Adobe’s products, it is natural for their support experts to not be able to cover every product. However, it is frustrating as a customer and an integrator to have different places to go to get support depending on the product. Product integration points are especially challenging as the customer or implementer has to determine how to solve a problem with separate input from two different product support teams.

Instead of instructing customers to contact customer care, open a Daycare ticket or contact SPP help, AMS should be the single point of contact to coordinate all support activities. Thus, making this process seamless to the end customer.

This would include the onboarding process as well. Instead of the customer working with the Target and Analytics and AEM teams, the AMS team would coordinate the customer’s onboarding to the entire Adobe Experience Cloud.

 

Adobe Managed Services for Any Client

 

With this new, more tailored solution, AMS would have an offering for any client situation and need. Indeed, Adobe could increase their penetration within clients by offering multiple solutions for different business needs.

The post An Outsider’s Recommendations for Adobe Managed Services appeared first on Perficient Digital.

Where’s the Workflow??

$
0
0

Workflows are some of the most powerful tools in the toolbox of any AEM developer, however, due to some questionable UI choices in the TouchUI, they are somewhat buried. To understand why, let’s take a look at the process for starting a workflow from the AEM Assets console:

Starting a Workflow in AEM Assets

Image credit Ahmed Musallam

 

Which of course leaves our authors wondering…

Where's the workflow??

 

Naturally, we have the option to just deal with the usability challenge and address it with author training, but what if you wanted to extensively use workflows? Making authors use a hard to find feature is going to impinge adoption so how can you improve the user experience without extensively customizing the AEM UI?

 

Sling Resource Merger

 

You’ll notice that the AEM UI components show up under the path /mnt/overlay[path], which means they are actually generated by Sling Resource Merger. This Apache Sling feature generates a merged set of resources based on multiple source paths, in the example of the AEM Assets UI, combining the paths:

  • /apps/dam/gui/content/assets
  • /libs/dam/gui/content/assets

into a single path:

  • /mnt/overlay/dam/gui/content/assets

As with most AEM / Sling functionality, Resources under /apps will take precedence over resources under /libs, thus enabling a clean way to override the default AEM UI without making any modifications of /libs.

NOTE: Any modification / override will need to be maintained, so keep in mind that during an upgrade the node structure, resource types or attributes may change so keep that in mind when deciding whether or not to overlay a default feature.

Step 1: Add the Workflow Action

To push the workflow button up in the selections action list, you can copy:
/libs/dam/gui/content/assets/jcr:content/actions/selection/create/items/createworkflow
to
/apps/dam/gui/content/assets/jcr:content/actions/selection/startworkflow
and then update the sling:resourceType AND variant attributes to display as a regular action instead of a sub-action.

The Merged Workflow Button

 

Step 2: Order the Workflow Action

By default the new workflow action will be put at the end of the action bar, so let’s have Sling Resource Merger insert the action between before some of the other actions. For example to place the Workflow button before the Extract Archive button, add the attribute: sling:orderBefore=”extractarchive”. When you refresh the Assets UI, you can now see that the button is now directly following the create button: 

 

Ordered Workflow Button

 

Step 3: Hide Create > Workflow

Since we don’t want the same action to be available in multiple places, we can hide the original button by adding a node at:

/apps/dam/gui/content/assets/jcr:content/actions/selection/create/items/createworkflow

with the property sling:hideResource=true

Additionally, to prevent the create button from shifting to the last position, we need to set sling:orderBefore=”startworkflow” on the node:
/apps/dam/gui/content/assets/jcr:content/actions/selection/create

Try It Yourself

I’ve created a ready to go package if you wanted to try the tweak yourself. As noted above, you will need to check across AEM versions. I’ve tested it on 6.4 and 6.5, but even between those versions the icon for workflow has changed.

Download the Package

I hope this helps you understand how you can use Sling Resource Merger to tweak the AEM UI as well as having some ideas of what impact this can have on your upgrade process.

The post Where’s the Workflow?? appeared first on Perficient Digital.

Attack of the AEM Link Checker!!

$
0
0

Nearly every user of Adobe Experience Manager underestimates the AEM Link Checker. Most people think of the AEM Link Checker as that annoying feature that incorrectly strips links in AEM. But, it can do far more.

Not only will the AEM Link Checker remove links and incorrectly flag links as broken, but it can also bring an AEM instance to its knees.

This isn’t to say that the idea of having a tool to check links is a bad idea. A good crawler, like Screaming Frog, is a vital tool in every digital marketer’s toolbox, but why is it run on every request?

AEM Link Checker in the Wild

Recently, we had this happen with an AEM instance. The instance had externalized links in the navigation so that the navigation could be used on multiple sites. As additional pages were brought into AEM, the load the AEM Link Checker inflicted upon the instance increased geometrically. This eventually leads to severe performance problems.

Initially, we assumed that the increasing performance problems were due to an errant query or Java Filter. However, a particular heap dump told a very different story.

java.lang.Thread.State: RUNNABLE
at java.util.AbstractCollection.containsAll(AbstractCollection.java:317)
at java.util.AbstractSet.equals(AbstractSet.java:95)
at com.day.cq.rewriter.linkchecker.LinkInfo.isSame(LinkInfo.java:228)
at com.day.cq.rewriter.linkchecker.impl.LinkInfoStorageImpl.putLinkInfo(LinkInfoStorageImpl.java:375)
at com.day.cq.rewriter.linkchecker.impl.LinkCheckerImpl.getLink(LinkCheckerImpl.java:275)
at com.day.cq.rewriter.linkchecker.impl.LinkCheckerTransformer.startElement(LinkCheckerTransformer.java:289)
at org.apache.cocoon.xml.sax.AbstractSAXPipe.startElement(AbstractSAXPipe.java:97)
at com.day.cq.mcm.core.newsletter.NewsletterTransformerFactory$NewsletterTransformer.startElement(NewsletterTransformerFactory.java:132)
at com.day.cq.rewriter.htmlparser.DocumentHandlerToSAXAdapter.onStartElement(DocumentHandlerToSAXAdapter.java:105)
at com.day.cq.rewriter.htmlparser.HtmlParser.processTag(HtmlParser.java:640)
at com.day.cq.rewriter.htmlparser.HtmlParser.update(HtmlParser.java:343)
at com.day.cq.rewriter.htmlparser.HtmlParser.write(HtmlParser.java:196)
at java.io.Writer.write(Writer.java:192)
- locked <_0x00000006aab74560> (a com.day.cq.rewriter.htmlparser.HtmlParser)
at java.io.PrintWriter.write(PrintWriter.java:456)
- locked <_0x00000006aab74560> (a com.day.cq.rewriter.htmlparser.HtmlParser)
at org.apache.sling.scripting.core.impl.helper.OnDemandWriter.write(OnDemandWriter.java:75)
- locked <_0x00000006aab9c3c0> (a org.apache.sling.scripting.core.impl.helper.OnDemandWriter)
at java.io.PrintWriter.write(PrintWriter.java:456)
- locked <_0x00000006aab9c3c0> (a org.apache.sling.scripting.core.impl.helper.OnDemandWriter)
at org.apache.sling.scripting.core.impl.helper.OnDemandWriter.write(OnDemandWriter.java:75)
- locked <_0x00000006aab9c428> (a org.apache.sling.scripting.core.impl.helper.OnDemandWriter)
at java.io.PrintWriter.write(PrintWriter.java:456)
- locked <_0x00000006aab9c428> (a org.apache.sling.scripting.core.impl.helper.OnDemandWriter)
at java.io.PrintWriter.write(PrintWriter.java:456)
- locked <_0x00000006aab9c478> (a java.io.PrintWriter)
at java.io.PrintWriter.write(PrintWriter.java:473)
at org.apache.sling.scripting.sightly.apps.example 

To confirm, I reviewed the logs and then grepped the error log to confirm what I was seeing:

grep -wc 'External links for host .* has reached the maximum number of' error.log

 

Shockingly, this returned over 1,300,000 instances of the log message over the last 24 hours. In order to determine what domains were causing the issues, I then ran another command to just find the unique messages:

grep 'External links for host .* has reached the maximum number of' error.log | sort --unique

 

From there, I ran the original grep command with specific domains to determine what domains were most responsible.

Saving AEM from the Link Checker

Ideally, the AEM Link Checker should not be enabled in production instances to ensure that it does not impact performance. If this is not an option due to the potential for other side effects, you can configure the “Link Check Override Patterns” in the “Day CQ Link Checker Service” as described in this Adobe HelpX Article.

For instance, to disable checking of the domain www.example.com, you could use a regular expression like:

^https?:\/\/www\.example\.com

 

After configuring the AEM Link Checker to ignore the indicated domains, the AEM instance immediately returned to a stable state.

Hopefully, you’ve already disabled the AEM Link Checker in your production instances. If not, I hope this article helps you identify when it causes performance problems and helps resolve the problem.

 

The post Attack of the AEM Link Checker!! appeared first on Perficient Digital.

I’m sorry, but you have a case of… WordPress

$
0
0

Have you ever found out you owned a website you never knew about? Do you regularly get emails with “comments” about certain types of enhancement and EXPERT SEO SERVICES!!!? Does your ITSec know the website you’re calling about before you tell them it’s compromised? If so, you may have a case of WordPress.

WordPress is a common infection and spreads rapidly. All it takes is one employee with a credit card and desk far enough away from IT and marketing and next thing you know you have a full-blown pandemic of “temporary” ill-branded microsites.

Thankfully, an outbreak of WordPress can be cured with a full panel of server antibiotics and Perficient’s Open Source WordPress to AEM migration tool.

 

Why not WordPress?

 

In all seriousness, while WordPress is an easy tool to get started with a blog, in larger organizations, it’s a struggle to keep multiple WordPress instances secured, performant, aligned with brand / IT standards. Having additional websites, systems, and hosting providers adds complexity to maintain an organization’s digital presence. So, aligning on a single, enterprise platform eases the burden on IT and marketing teams.

Given that you’re reading a post by an Adobe architect, it should be no surprise that I’d recommend Adobe Experience Manager as an enterprise Digital Experience Platform. The Adobe Experience Cloud allows your organization to manage content across multiple sites and build an integrated, personalized digital experience using a single suite of tools.

 

WordPress vs. AEM

 

Getting to AEM

 

AEM has a much more flexible and complex content model than WordPress. In WordPress, each piece of content, including pages, posts and assets, is represented as a single document with content and metadata. Each widget on the page is represented as markup inside the content. In AEM, all content is represented as a complex element where the content and metadata are one and the same.

Additionally, WordPress’ default export mechanism exports the content as a single WRX (extended RSS) file. This supports transfers between instances of WordPress but requires some work to transfer to another system.

 

WordPress to AEM Migration Flow

 

To overcome these challenges, Perficient developed tooling to transform content from WordPress to AEM. This is a four-part process:

  1. Extract the content from WordPress in a WRX file
  2. Transform the content into separate files and Metadata CSV files using the WordPress Extract Script
  3. Create a content package with the AEM Migration Script
  4. Load the content using the AEM Package Manager

 

At the end of the process, your content will be fully converted into AEM content, mapped into appropriate templates and components, and ready to publish. The process even takes care of downloading images and packaging them up to be loaded into AEM Assets.

Seeing is Believing

 

Excited about the prospect of consolidating your disparate WordPress sites to AEM? Contact us and send us your WordPress WRX export and we’ll demo mapping your content into AEM.

Trying it out on your own and have questions? Leave a comment below!

The post I’m sorry, but you have a case of… WordPress appeared first on Perficient Digital.

Fumble! Successfully Navigate the Three Primary Project Handoffs

$
0
0

Most programs we deliver at Perficient Digital follow the Plan, Build, Run methodology for our work and client delivery. We chose this methodology for how it aligns with how we execute programs as consultants to our clients.

Even with the defined phases of Plan, Build, Run, teams run into challenges. This is especially true as a program moves between the phases and different handoffs occur between and within the teams.

Some of the most common challenges include:

  • Design / Architecture teams designing a solution in the “ivory tower” that can’t be executed
  • Implementation teams not understanding the business goals and building something that works… but doesn’t meet the business needs
  • Lack of knowledge / handoff to the support teams supporting the solution

As an end-to-end solution provider, Perficient Digital helps guide clients through these challenging transition points to deliver a successful program. Below are some thoughts to help your team navigate these transition points.

 

The Three Transition Points

The three primary transition points between project phases are:

  • Conception to Plan – when a project is first getting kicked off, the challenge is to capture the needs and requirements of the business and design a solution to resolve the need and still be possible to implement.
  • Plan to Build – having requirements is one thing, executing then is something else. Any solution build has its challenges, but a failed transition between planning and building is fatal.
  • Build to Run – whether the same team or another team builds the application, transitioning from build to run requires a different set of skills and operational processes. If you don’t transition completely or cleanly, it can lead to an unreliable application or knowledge gaps.

Crossing the Bridge

 

Managing the Transitions

 

Successfully transitioning between project phases usually comes down to two things:

  • Consistency
  • Communication

Consistency

As you transition across project phases, you will need different skill sets. Successful projects have a “core team” of skilled people to ensure the team develops and cultivates tribal knowledge. The core team should include the dream team and a Project Owner to provide a vision for the project’s success.

Having consistent people is important, but the team must also follow consistent processes and best practices. This includes:

  • Documenting Decisions
  • Documenting the Solution
  • Documenting Work / Tasks
  • Creating new Team Member Onboarding
  • Creating Tests of Deliverables
  • Creating and Following Development Best Practices
  • Automating Quality with CI/CD
  • Creating and Performing Training

Communication

As a project goes on and transitions between the project phases, different people will need to roll on and off the project. Effective communication is vital to ensure that new core and supplemental team members have a clear vision of the project goals.

Although project transitions are already chaotic and busy, communication is even more vital. Project teams need to spend time communicating with the new team members and transitioning out to ensure a clean transfer of knowledge.

 

The post Fumble! Successfully Navigate the Three Primary Project Handoffs appeared first on Perficient Digital.


Dynamic Dropdowns in AEM Content Fragments

$
0
0

In this post, I’ll show you how to easily and cleanly create a dynamic dropdown in an AEM Content Fragment Model driven by an ACS AEM Commons Generic List.

What are Content Fragments?

 

But first, what are Content Fragments? Content Fragments are a powerful feature in Adobe Experience Manager (AEM) for managing structure content.

Each Content Fragment has a model which defines the structure of the Content Fragment. To edit the model, Adobe provided an editor with common fields, including text fields, number fields, and dropdowns (called Enumerations).

 

Content Fragment Editor

 

Why isn’t this Out of the Box?

 

Unfortunately, when Adobe implemented the Content Fragment Model editor, they didn’t consider extensibility. The fields are very limited and there is no API for adding custom fields.

Despite these significant shortcomings, Content Fragments make managing simple content structures effortless, due to their simplicity and ease of use.

While Adobe made it harder for implementors by failing to follow best practices, like using Sling Resource Merger or structuring components in a sane manner, we are using Apache Sling. So, we can “kick it old school” and overlay the component.

 

Our Mission Statement

 

The Enumerations field included in Content Fragment Models only supports setting a static set of options. This is good enough for slideware, but in real life, it’s inadequate. A couple problematic use cases include:

  • Multiple models sharing the same set of values
  • Lists of options where a new options needs to be dynamically added
  • Option lists which change their options in the context of where / how the Content Fragment is used

 

The Solution

 

To create a dynamic dropdown, we’ll overlay the JSP script used to generate the dropdown options from the static list:

/libs/dam/cfm/admin/components/datasources/optionrenderer/optionrenderer.jsp

 

By creating a script at:

/apps/dam/cfm/admin/components/datasources/optionrenderer/optionrenderer.jsp

 

Since Sling prioritizes /apps over /libs when it looks up scripts, our script will get called instead of the original script.

The original script is simple; it hackily converts the String of comma-separated options into a com.adobe.granite.ui.components.ds.DataSource object and then sets that as a request object. Pretty easy to reproduce! But of course, we don’t want to break the existing functionality.

To avoid breaking the existing functionality, we can prefix all of our dynamic dropdowns with a known prefix. This will also allow us to even have multiple different types of dropdown population methods.

In this example, we’ll use the prefix: “acs-commons-list:” for populating a dropdown of the values of an ACS AEM Commons Generic List. Additionally, we have to use a Lambda function to map the properties in the Generic List into the format used by the DataSource. All said and done, here’s what the script looks like:

 

 

Once we have the script in place, we can use dynamic and static dropdowns together.

 

Dynamic Dropdowns

 

With this technique, we are no longer constrained to static dropdowns with AEM Content Fragments. With more prefixes, we can have even more options to populate dynamic dropdowns.

 

The post Dynamic Dropdowns in AEM Content Fragments appeared first on Perficient Digital.

Visualize OSGi Service Graphs with Composum

$
0
0

Here’s a neat trick for AEM developers and architects: you can create a diagram representation of the service dependencies using Composum. For those not familiar, Composum is an Open-Source project based on Apache Sling.

To create a service dependency diagram, you will need to install two additional dependencies:

Once you install the dependencies, you can access the Composum Service Graph web console at /system/console/servicegraph.

Screenshot of the Service Graph Web Console

 

Using the Service Graph Web Console

 

The Service Graph Web Console has a couple fields, the most important being the Classnames Regex. You can put any regular expression to filter what classes should be including:

  • ^com.composum
  • ^com.day.cq.wcm.foundation.forms

Every OSGi Service matching the regular expression will be included in the graph. Note that having too broad of a regular expression, such as ^com.adobe or ^org will cause the graph to fail to render, so make sure to narrow down as much as possible.

Downloading as an Image

 

Currently, the Service Graph is only available as an SVG, not a downloadable image, but using the following JavaScript snippet you can download the Service Graph:

I’ve also created an issue with the Composum team to include this in their next release.

 

The post Visualize OSGi Service Graphs with Composum appeared first on Perficient Digital.

Revealing Hidden Oak Nodes / Properties

$
0
0

Did you know there are properties you can’t see in your Apache Sling / Adobe Experience Manager repository? Jackrabbit OAK includes the concept of hidden nodes and properties. Hidden nodes and properties are prefixed with a colon and are not visible to consuming applications.

Examples include :nestedCugs and :topCugCnt which are used to store the state of Jackrabbit Closed User Groups.

If you are lucky, you will never have to deal with hidden properties, but if you do, you should know that the Oak Run JAR includes a couple of very helpful utilities for revealing these properties.

  • Oak Run Console – Interactive CLI console for traversing down through the Jackrabbit Oak repository
  • Oak Run Explore – Java GUI tool for exploring the current state of the Jackrabbit repository

Both of these tools have similar functions but operate quite similarly. In my experience, the console is quicker whereas the GUI is easier to use.

Getting Oak Run

The first step to getting Oak Run is to find the version required for your Apache Sling / AEM instance. You can find it by checking the version of the Oak Core bundle:
http://localhost:4502/system/console/bundles?filter=(Bundle-SymbolicName=org.apache.jackrabbit.oak-core)

Searching for the OAK Core Bundle

 

From there, you can download the correct version of the Oak Run jar from Maven:
https://search.maven.org/search?q=g:org.apache.jackrabbit%20AND%20a:oak-run&core=gav

Using Oak Run Console / Explore

Once you have the Jar downloaded copy it into the installation directory and then run the commands as such:

AEM:

java -jar oak-run-[version].jar [command] crx-quickstart/repository/segmentstore

Sling CMS / Apache Sling:

java -jar oak-run-[version].jar [command] sling/repository/segmentstore

Running the commands you will get a screen like the following.

Oak Run Explore

Oak Run Explorer

A few nice things you’ll notice in the explore GUI:

  • Tree view of the Oak repository
  • ALL nodes and properties including the hidden ones
  • Repository size by node tree

Oak Run Console

Oak Run Console

The console allows you to navigate the Oak repository like a filesystem and has a number of nifty commands. You can find out more by entering :h or :help.

The post Revealing Hidden Oak Nodes / Properties appeared first on Perficient Digital.

Improving Bulk User Creation in AEM 200x

$
0
0

Recently, we had a particularly challenging problem where an AEM website needed to support up to several hundred thousand logins within approximately a 2-hour window. To support this level of load, we couldn’t have user profiles get populated as the users logged in. Instead, the team created a job to populate the users and groups ahead of time. A couple of days later, we knew we had a problem, the job was still running!

After approximately, three days, the job finally finished, so we had a baseline of the performance. To say the least, we had exceeded the off-hours window before users would start accessing the system in bulk.

Here’s how we were able to optimize the user synchronization process from 3 days to 15 minutes.

Hashing Users

Our first attempt to resolve the issue was to hash the user’s ID to create a hashed path. We used the SHA-1 algorithm to hash the user’s principal and generate the user’s path, broken down into two character segments. This limited the number of sub-items in each folder to 128 folders/users. This helped as AEM does generally not handle a large number of sub-items well.

This resulted in a significant performance increase when creating users, but updating users was still far too slow.

 

Calculate & Create

 

The next step to optimize the update of users. After monitoring the job, I found that the process to find and check users was a major performance concern. Since we were already hashing the user paths and creating them at known locations, I could optimize this lookup by retrieving the users and groups by path and creating a lazy-loading in-memory cache of all the users and groups for subsequent updates. Since only the job would be creating or deleting users, we could read from the cache to avoid having to query the JCR to check if a user or group exists.

To further optimize saves, I optimized the process away from streaming the users and one at a time. Instead, the code calculates the differences and creates / updates the users in bulk. These changes resulted in a drastic increase in performance with the job completing in under an hour on both create and update.

Unfortunately, performance hit the wall once again when assigning the users into groups.

 

Hashed Sub-Groups

 

The problem with adding users to groups has to do with how Jackrabbit groups persist membership. Jackrabbit saves group members as an array of User ID’s. To check and then add group members, our code was performing an array traversal over several hundred thousand members.

Similar to how we handled the hashing, we leveraged the principal hash to create child groups and assigned users into the child groups by their initial hash segments. This ensured each group had a relatively small number of members but allowed us to retrieve the groups with an O(n) operation.

Finally, we add each child group into the parent group. This kept the number of direct parents smaller (allowing us to only traverse the direct members) which increased performance while allowing for permissions to still work using membership inheritance.

 

Wrapup

 

After these optimizations were put in place, the update time was cut from 3 days to 15 minutes. Success!

Handling massive numbers of users and groups in AEM can cause severe performance issues. By leveraging hashing and sharding group and user folder membership you can handle up to hundreds of thousands of users in AEM with ease.

The post Improving Bulk User Creation in AEM 200x appeared first on Perficient Digital.

Early Thoughts on the Adobe Client Data Layer

$
0
0

Last month, Adobe Open Sourced an Event-Driven Data Layer implementation. They call it the Adobe Client Data Layer and you can find it on GitHub:

https://github.com/adobe/adobe-client-data-layer

The project is currently a tech preview and should not be used in production. However, for the more enterprising among us, it’s fun to investigate bleeding edge solutions from Adobe.

I’ve tried out the Adobe Client Data Layer and I believe soon this will be the way to implement a DataLayer with the Adobe solutions. While the final API / implementation of the Adobe Client Data Layer is not complete, here are some initial thoughts.

Things I Like

It’s Event-Driven!!

So what’s the big deal? Most DataLayer implementations on the Adobe Experience Cloud followed the WC3 CEDDL specification. The problem was that this specification described a static DataLayer. Events, data, etc are properties, but the DataLayer maintains no history of any changes. This was fine for static sites where most interactions required a page refresh but are outmoded in this era of Single Page Applications and AJAX.

You could, of course, create your own Event-Driven Data Layer, but that’s a significant investment in code. Adobe’s lack of a good solution for this has been the Achilles Heel of many an Adobe Analytics implementation, which instead relies on clunky workarounds. Now the DataLayer itself can respond to data / interaction pushes and Launch can listen to those events.

Just Enough Structure

The Adobe Client Data Layer imposes some structure on the data you pass in. The top-level element defines what you are pushing in including:

  • Data
  • Events
  • Listeners

Below that it’s up to the implementor to decide how to structure the data.

Listeners

Listeners are an interesting concept, you can register a listener to listen to events to occur and then invoke some code to handle the event. Some interesting concepts include:

  • Getting user profiles / data when the DataLayer loads
  • Performing some calculations when a form is submitted
  • Invoking another action / tag when an event occurs

Areas of Improvement

Not surprisingly, given this isn’t even released, there are some areas of improvement.

Integrations

It’s not clear at the moment, how the Adobe Client Data Layer will be integrated into the Adobe solutions, though again it is still early. For sure, it would be great to have integrations right into Adobe Launch, Target and Experience Manager.

One other integration issue I did see is with the use in conjunction with Google Tag Manager. Not that it’s a common scenario to deploy Launch and GTM together long term, but it does happen during tool migrations. Allowing renaming should resolve this issue.

Getting State

Currently, the way to get the state of the DataLayer is to call the getState() method. This will require more code in certain situations than if the state was exposed as a property. I also understand there are downsides to recomputing the state with every push.

Next Steps for the Adobe Client Data Layer

As Adobe clearly states, the Adobe Client Data Layer is still a tech preview, but I would encourage you to take a look and provide feedback or open an issue.

I don’t have special insight into (and I feel like asking may put me in a NDA situation) Adobe’s roadmap for the Adobe Client Data Layer. Judging by where they are in development, I’m hoping that by Adobe Summit 2020, the Adobe Client Data Layer will be ready for primetime use and they’ll have some reference implementations to show!

The post Early Thoughts on the Adobe Client Data Layer appeared first on Perficient Digital.

Bridging the Data / Content Gap: Bringing Adobe Analytics into AEM

$
0
0

As marketers we work tirelessly to extract meaningful data from our digital experiences, but how often do we actually close the loop?

In this blog post, we’ll walk through how to retrieve Adobe Analytics Workspace report data from Adobe Experience Manager using Adobe I/O. Our use case is that we want to prompt the user of a search component in AEM with the top search terms as reported by Adobe Analytics.

Step 1: Setup AEM & Adobe Analytics I/O Integration

To get started, we can use the excellent Adobe I/O APIs feature available in the ACS AEM Commons. With this API, we can avoid the tedious step of creating the JWT authentication with Adobe I/O.

We still must gather the required credentials to connect to Adobe I/O.

First, in AEM navigate to the OSGi Configuration Console and open ACS AEM Commons – Adobe I/O Integration Configuration. You should get a screen like this:

 

ACS AEM Commons Adobe I/O Integration Configuration OSGi Console

 

Next, login to console.adobe.io and navigate to your integration. From here, you will access the credentials for connecting to Adobe I/O. If you have not created an integration already, follow the steps to create a Service Account Integration. Make sure to grant your Service Account access to the Adobe Analytics Service.

Most of the credentials we need are located on the initial screen for the integration:

 

Adobe I/O Integration

 

From the Adobe I/O Integration Overview screen, copy the following fields into the ACS AEM Commons – Adobe I/O Integration OSGi configuration:

  • API Key (Client ID) -> ClientId
  • Client secret -> ClientSecret
  • Organization ID -> OrgId
  • Technical account ID -> TechAccountId

Your PrivateKey should be available on your computer and should match one of the Public keys associated with the I/O Integration.

Finally, set the LoginClaim to: https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk and save the configuration.

Step 2: Configure I/O Endpoint Instance

Now that we have AEM configured to connect via Adobe I/O, we can configure the Analytics API 2.0 connection. Reopen the OSGi Configuration Console and select ACS AEM Commons – Adobe I/O Endpoint Factory Configuration +.

 

ACS AEM Commons - Adobe I/O Endpoint Factory Configuration

 

The ID is arbitrary. You can set it to something meaningful and concise. Set the Method to POST and then enter the following for the URL Endpoint:

https://analytics.adobe.io/api/{{companyId}}/reports

What is companyId? It’s not clear / straightforward from the API, but this is another ID for your company you can’t get directly from the I/O Console. The easiest way to get this is to use the Adobe Analytics 2.0 Discovery Endpoint. Since this won’t change, you can keep the value handy.

Finally, add the following Service specific Headers:

  • x-api-key:{{API Key (Client ID)}}
  • x-proxy-global-company-id:{{companyId}}
  • Accept:application/json
  • Content-Type:application/json

And save the configuration.

Step 3: Get Workspace Request

Adobe Analytics Workspace natively uses the Adobe Analytics 2.0 API, so we can reproduce any Workspace report via the API. In our case, we’ll create a simple report with just the prop we want to report on.

 

Simple Adobe Analytics Workspace Report

 

Once you have the report created, follow the guide on enabling Workspace debugging, select the bug icon, and then copy the JSON Request. You should have something like this:

{
    "rsid": "myreportsuite",
    "globalFilters": [
        {
            "type": "dateRange",
            "dateRange": "2019-11-01T00:00:00.000/2019-12-01T00:00:00.000"
        }
    ],
    "metricContainer": {
        "metrics": [
            {
                "columnId": "0",
                "id": "metrics/occurrences",
                "sort": "desc"
            }
        ]
    },
    "dimension": "variables/propXX",
    "settings": {
        "countRepeatInstances": true,
        "limit": 50,
        "page": 0,
        "nonesBehavior": "exclude-nones"
    },
    "statistics": {
        "functions": [
            "col-max",
            "col-min"
        ]
    }
}

Step 4: Create OSGi Service

The final step is to create the OSGi Service to connect to the Adobe Analytics I/O API from AEM. This service will use Endpoint Instance ID we created in Step 2 to reference the correct EndpointService instance and call the perform_IOAction method with the Adobe Analytics Workspace JSON we retrieved in Step 3.

In the code sample below, I’m creating a Scheduled task to retrieve the values every 24 hours.

 

package com.company.internal.scheduler;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import com.adobe.acs.commons.adobeio.service.EndpointService;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

@Component(service = Runnable.class, property = { "scheduler.expression=0 1 0 ? * *" })
@Designate(ocd = AnalyticsReport.Config.class)
public class AnalyticsReport implements Runnable {

    @ObjectClassDefinition(name = "Analytics Report")
    @interface Config {

        @AttributeDefinition(name = "Report Suite ID")
        String reportSuiteId();

        @AttributeDefinition(name = "Variable ID")
        String variableId();

    }

    private static final String DATE_FORMAT = new String("yyyy-MM-dd:00:00.000");
    private Config config;

    public void activate(Config config) {
        this.config = config;
    }

    @Reference(target = "(id=analytics-report)")
    private EndpointService analyticsReport;

    public void run() {
        JsonParser parser = new JsonParser();
        Date end = new Date();
        Calendar cal = new GregorianCalendar();
        cal.setTime(end);
        cal.add(Calendar.DAY_OF_MONTH, -30);
        Date start = cal.getTime();
                SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
        JsonElement json = parser.parse("{\"rsid\":\"" + config.reportSuiteId()
                + "\",\"globalFilters\":[{\"type\":\"dateRange\",\"dateRange\":\"" + dateFormat.format(start) + "/"
                + dateFormat.format(end)
                + "\"}],\"metricContainer\":{\"metrics\":[{\"columnId\":\"0\",\"id\":\"metrics/occurrences\",\"sort\":\"desc\"}]},\"dimension\":\"variables/"
                + config.variableId()
                + "\",\"settings\":{\"countRepeatInstances\":true,\"limit\":50,\"page\":0},\"statistics\":{\"functions\":[\"col-max\",\"col-min\"]}}");
        JsonObject ioResponse = parser.parse(analyticsReport.performIO_Action(json.getAsJsonObject()).toString())
                .getAsJsonObject();
        
        // TODO: Store / do something with the response

    }
}

And there you have it! In four steps, we’ve retrieved data out of Adobe Analytics into Adobe Experience Manager using Adobe I/O. Once you have the data, you can save the values into the AEM Repository or make it available directly from an OSGi service.

Bonus: Swagger Java Code Generation

In the example above, I’m using Gson to parse / generate the JSON requests for Adobe I/O. Since Adobe publishes Swagger documentation it would be possible to use the Open API Generator Maven Plugin to generate the models for accessing and retrieving data from the Adobe Analytics 2.0 API.

 

The post Bridging the Data / Content Gap: Bringing Adobe Analytics into AEM appeared first on Perficient Digital.

Sling CMS Version 0.14.0: New Capabilities and Experience Improvements

$
0
0

It’s been awhile since the last release of Sling CMS. The latest release, 0.14.0, brings tremendous new capabilities and dramatic improvements to the authoring experience to Sling CMS.

New Capabilities

Release 0.14.0 brings some exciting new capabilities to supplement the core content management features of Sling CMS to handle common web use cases.

New Capability #1: Forms

 

The Sling CMS Reference project already includes a lot of the base components, but didn’t have a good solution for building forms. Conceptually, forms are composed of three parts:

Form Value Providers

 

Form value providers provide the default values for the form. An example form value provider is included in the reference app, which loads the form values from the user’s profile.

Form Value Providers are implemented as a Sling CMS Component coupled with a Java Class implementing the FormValueProvider interface.

Form Fields

Form fields are used to display the actual fields in the form. Examples provided include:

  • Honeypot – A simple spam prevention hidden field
  • Selection – Support for checkboxes, selects and radio buttons
  • Textarea – Simple textarea
  • Textfield – Textfields including HTML5 validation

Form Fields are implemented as a Sling CMS Component coupled with a Java Class implementing the FieldHandler interface. The FieldHandler implementation should handle all of the aspects of handing the field including validation.

Form Actions

Form actions handle the results of the form submission. Similar to the other form components, they are composed of a Sling CMS Component and an OSGi component implementing the FormAction interface.

There are three implementations provided with the reference application, including:

 

New Capability #2: Image Transformations

Image transformations were initially introduced in Sling CMS 0.12.0, however they got a rebuild and enhancement in Sling CMS 0.14.0. The new image transformations are based on Sling Context-Aware Configuration created at /conf/[conf-name]/files/transformations.

Each configuration is a series of instructions on how to transform a source image into the target using the Thumbnailator library. Currently, there are two supported transformations:

  • Size – resize the image to fit within a width and height
  • Crop – Crop the image to fit within a width and height, specifying a crop direction

Image Transformations are stored underneath sling:File assets as renditions and internally are used by Sling CMS to render the grid view.

 

Authoring Experience Improvements

 

I use Sling CMS for my personal site, so the authoring experience has a direct impact on my productivity. The focus of this release was to make tangible improvements.

Improvement #1: Drag and Drop Component Re-Ordering

 

One of the more annoying features of Sling CMS before this release was that to reorder components, you had to use the move icon and could only move them within their current container.

With the latest release you can reorder components within a container or into other containers by just grabbing their edit bar.

Some of the authoring experience improvements include:

  • Drag and Drop Component Reordering
  • Slimmer edit bars
  • New grid view for Sites and Static Content

 

Drag and Drop

 

Improvement #2: New Grid View for Sites & Static Content

 

In previous versions of Sling CMS, the only view of content was a tabular display. This worked pretty well for text content, but wasn’t visually appealing for images / assets. The new grid view is default for Sites and Static content, but can be toggled off or set as not default in the user settings.

New Sling CMS Grid View

 

Improvement #3: User / Group Console

 

Previously, to modify users and groups, you had to leave the Sling CMS look and feel and use the Composum User / Group management tool With Sling CMS 0.14.0, Sling CMS now has a console for managing users and groups.

 

Sling CMS User / Group Console

 

Improvement #4+: UI Tweaks

 

I’ve tweaked the user experience for the editor to make a number of small changes and generally make it cleaner and more modern looking.

Developer Quickstart

Sling CMS is already easy to setup with the Vagrant and Docker images as well as it being a single JAR download. With the release of Sling CMS 0.14.0, developers will be able to create projects for Sling CMS with a single command:

mvn archetype:generate  \
  -DarchetypeGroupId=org.apache.sling \
  -DarchetypeArtifactId=org.apache.sling.cms.archetype \
  -DarchetypeVersion=0.14.0

 

With the new Sling CMS Archetype, creating a site in Sling CMS creating a new site with Sling CMS takes just over two minutes:

 

Sling CMS Create a Site

Looking to get started with Sling CMS? Download the latest release from GitHub.

The post Sling CMS Version 0.14.0: New Capabilities and Experience Improvements appeared first on Perficient Digital.


The 12 Questions of AEM-mas

$
0
0

T’was the week after Christmas and all through the blog, not an author was writing nor viewing the log(s).

Though my ideas are scarce I’ve had many a complaint and many had caused my language to not be that of a saint.

The 12 questions below are not constructive, but if Adobe were to consider them; it would not be destructive.

In the new year my usual posts will return along with our staff, but for now, I hope this post gives you a laugh.

The 12 Complaints of AEM-mas

Setting up the AEM Project Archetype

 

Why is setting up a project with the AEM project archetype like setting up a knockoff Android phone?

Holy Cow! Who knew that to develop a simple AEM project you needed 7 sub-modules!?!? I sure didn’t and frankly, nor do I think anyone does. Setting up the AEM project archetype requires first deleting 75% of the junk it creates.

There’s far too much going on in this project to be comprehensible and in my opinion, the whole idea of jamming all of the various components of an AEM project into a single Maven project is a bad practice. Yes, we want to produce a single deliverable, but why should the HTML code, Service integrations and Dispatcher code all be in the same repo? Crazyness!

JavaScript? Is that like jQuery?

 

Why do we pretend on AEM projects like Node JS builds don’t exist?

 

To be fair the AEM Project Archetype finally has an option to support Node builds, but it’s not even enabled by default.

ClientLibs were a great idea in the time of jQuery and downloading JavaScript libraries manually, but it’s 2019. Can we please just have good documentation on how to integrate front end build processes into AEM and retire ClientLibs?

 

I was going to find a meme about the AEM Projects console, but it's not worth wasting the time...

Why does the Projects console exist?

Seriously. Why?

It's 'flexible' as long as you only do the 5 things it can do...

Why is the Asset Metadata Schema Editor so Inflexible?

The AEM Assets Metadata Schema editor is a great idea! But holy cow, the implementation is so bad!

The only explanation I can come up with is that the team which created it had never worked on AEM before they started. It’s so rigid, you can’t even define your own field types! There’s no real concept of extension so if it doesn’t have what you want… too bad.

Features!! All the features everywhere!!

 

Why do we need to reinvent the wheel?

Theres no reason for a number of things in the AEM ecosystem to exist since there are already better options in the market and they provide no tangible value. Some of the more egregious examples:

  • HTL – who needs another templating language when you already have JSP, Thymeleaf, Handlebars, etc. Everything in HTL could be created somewhere else and be better than HTL
  • Cloud Manager – why did Adobe custom make a CI tool instead of using Azure DevOps / GitHub Actions or Jenkins or name any established player? Yeah… I don’t know either

 

In theory, they're great!

 

Has anyone at Adobe tried using the Core Components in Real Life?

 

Conceptually, the Core Components are great, but they are a nightmare from an extensibility perspective. Here’s a clue: NO ONE WANTS TO ADAPT THEIR HTML TO YOUR CMS!!! Most projects are designed by people who have no reason to know or care about how the Core Components structure their HTML so why does making trivial changes to the Core Components HTML require completely overlaying the HTL for the component?

Then there’s the matter of the Sling Models backing the Core Components. I know that architecturally hiding the implementation details makes things easier for Adobe because they’re not responsible for changes implementors make, but wow it makes simple changes hard.

The number of clicks to do anything in AEM is too damn high!!

 

Does mobile support really require a dozen clicks to do anything?

 

Touch UI does provide mobile support which is nice… for the 5 people who’ve ever authored a page on their phones, but it gives your index finger a workout. Most interactions that used to take 1-2 clicks now take at least 4-5. I was under the impression that the idea of mobile-first was to create a great experience on mobile, not drag desktop down to a mediocre experience.

What we have here

 

Do any teams at Adobe communicate?

At least Adobe uses a relatively consistent UI framework, but holy cow, even within AEM parts of the application are implemented completely inconsistently. The UI and implementation details of Forms, Sites and Communities are radically different. These inconsistencies result in significant duplication and even security issues.

It gets even worse when you integrate the rest of the Adobe Experience Cloud. It’s painfully obvious that most people at Adobe only deal with one product and the products aren’t set up to integrate together without additional work.

I don't deprecate code

Could we please just deprecate something eventually?

AEM is full of old code and semi supported features which have long sense outlived their utility, but still hang on like barnacles on a speedboat. Im sure many of them have some customer somewhere who still uses the, but is there a reason to not make the add one instead of part of the base product?

Would you ever miss CRX Explorer or the legacy reports or the foundation components? Probably not! Just cut the fat!

Who understands how AEM configurations are supposed to work?

 

Can we please just use Sling Context Aware Configurations?

 

Configurations in AEM are a hot mess. Different parts of the application use different configuration methods and most are poorly implemented. The sad thing is that there is a flexible, well implemented option already, Sling Context Aware Configurations (CA Configs).

Instead of the current mess of Cloud Configurations, AEM Configs and whatever mess Content Fragments use, if AEM converted entirely to Sling CA Configs would make configurations more flexible, cleaner and easier to use and understand.

 

Daycare UX

 

When is the last time Daycare was updated?

Support sites don’t usually win design awards but Daycare has to be one of the most dated and poorly designed applications in use at Adobe. Digging a little deeper, why is AEM support provided differently than the rest of the Experience Cloud?

For a company that talks about experience-driven business, Adobe’s customer experience at least as it relates to Daycare and support is very lacking.

No Extension for you!

 

Why doesn’t AEM have a module or plug-in system?

 

Yes, AEM is based on OSGI which has the concept of modularization, but AEM itself has no well-defined system for creating plugins or modules. Adobe has not produced good documentation on how to extend the tool template third-party integrations so developers do it themselves and often run into upgrade issues.

 

The post The 12 Questions of AEM-mas appeared first on Perficient Digital.

Thoughts on AEM as a Cloud Service

$
0
0

Today Adobe announced the availability of their newest offering AEM as a Cloud Service, a new version of AEM running natively in Adobe’s cloud as a Platform as a Service (PaaS). To be clear, this is different than their existing Adobe Managed Services or Cloud Manager offerings which run AEM as a standalone app running on Virtual Machines in the cloud.

Tadd Reves has already written up a great summary of the technical and architectural differences of AEM as a Cloud Service and Adobe Managed Services / traditional AEM or AEM Classic that I’d highly encourage everyone to go read.

In essence, AEM as a Cloud Service involves Adobe automatically provisioning and managing AEM instances running in Docker containers orchestrated by Kubernetes backed by a shared node / file store and a new provisioning model. For users of the end system, most things will stay the same including the AEM UI (for the most part), Cloud Manager for provisioning and the integration with the Adobe Experience Cloud tools.

For developers, system engineers, and Architects, however, this new architecture is a paradigm shift. It enables significantly greater scale and performance, at the cost of flexibility and some of the more unconventional capabilities of AEM.

All this begs the question before we all jump on the hype train, is AEM as a Cloud Service right for me?

How Adobe Hopes Customers will Respond to AEM as a Cloud Service

How Adobe hopes customers will respond to AEM as a Cloud Service

 

AEM as a Cloud Service Capabilities

Much like Adobe Campaign Standard vs Classic, AEM as a Cloud Service does not have feature parity with AEM Classic. This is likely partially by design as the flexibility of AEM in itself caused issues as it gave implementors a great deal of room to proverbially shoot themselves in the foot.

Based on a reading of the release notes and discussions with contacts at Adobe Engineering, here are a few things that will not be supported in AEM as a Cloud Service.

AEM as a Cloud Service vs AEM Classic

AEM Solutions

  • On-Premise Deployments – This is the biggest change, AEM as a Cloud Service is only available in Adobe’s cloud and will not be available for On-Premise deployments
  • AEM Forms – Not currently supported in AEM as a Cloud Service
  • AEM Screens – Not currently supported in AEM as a Cloud Service
  • AEM Communities – Is not supported, but frankly has been on life support for some time

Customer Solutions

  • Modifying App at Runtime – The /apps and /libs paths as well as the OSGi console are not modifiable at runtime and must be modified only via the standard deployment process
  • User-Generated Content – AEM as a Cloud Service does not support modifying content in the AEM Publish instances. You can use the Unified Profile Service, however many use cases will require bringing in a 3rd party data store
  • Complex Dispatcher Setups – AEM as a Cloud Service has limitations on the dispatcher configuration. I am still investigating how to support things like the Redirect Map Manager.
  • Complex Deployments – AEM as a Cloud Service has the same severe limitations as Adobe Managed Services in that it uses Cloud Manager for deployments

If your solution needs any of these capabilities, you will either need to figure out a different solution for these needs or avoid AEM as a Cloud Service at the current time.

If you do not, you can expect the following benefits from AEM as a Cloud Service vs On-Premise or Adobe Managed Services deployments:

  • Reduce support / maintenance efforts
  • Increased scalability
  • Continual product updates / enhancements (no more upgrades)

While Adobe has promoted customers can increase content velocity with AEM as a Cloud Service, I expect that it has more to do with improvements in the custom implementation than any direct result of AEM as a Cloud Service.

Where is Adobe Going with AEM?

The bad news for customers is that AEM Classic is now a “legacy” product and not getting the Engineering attention of AEM as a Cloud Service. At this point, Adobe has not started a Beta for AEM 6.6 and to be honest, I’m not expecting one.

The good news is that there are many customers who are not willing or cannot for various reasons move off AEM Classic. Thus I would expect similar to Campaign Classic vs Standard Adobe will eventually swing back around and support AEM Classic as they realize many of their largest customers aren’t moving to the cloud.

My hope is that at some point, Adobe will provide an image or recipe for customers to build out their AEM Clouds based on a prescribed pattern within the customer’s own data center or cloud tenant. I have not seen any indication of this being on Adobe’s roadmap, but I suspect customer’s objections with AEM as a Cloud Service will have more to do with not having control as any missing features.

What do I do now?

As with most major solution choices, the correct decision depends on the context. No matter the context, however, AEM as a Cloud Service makes Summit 2020 a must-attend for any Adobe Experience Manager customer.

On-Premise Customers

Evaluate whether the desire to run On-Premise is worth the cost and lack of investment Adobe will be putting into AEM Classic. With a sufficiently knowledgable partner and some architectural changes, most anything you can do AEM Classic should be possible in AEM as a Cloud Service in the near future.

Customers Relying on Features not Compatible with AEM as a Cloud Service

Evaluate different solutions and work with your technical contacts at Adobe to understand if / when Adobe will port the features to AEM as a Cloud Service.

Existing AEM Customers not on AEM 6.5

Consider moving to AEM as a Cloud service vs any efforts to upgrade AEM to the latest version. While there are benefits to AEM 6.5, moving to AEM as a Cloud Service could provide significantly more benefits and will get you on a platform more aligned to Adobe’s vision.

AEM Customers on AEM 6.5

Treat AEM as a Cloud Service as the next version of AEM and plan upgrade accordingly.

New AEM Customers / Implementations

Plan for AEM as a Cloud Service as the projected solution for new implementations. Depending on timelines and the full General Availability release of AEM as a Cloud Service, some new implementations may start on AEM Classic, but considering AEM as a Cloud Service as the end platform will help ensure that the solution does not cause issues when moved to AEM as a Cloud Service.

What’s next for AEM as a Cloud Service?

As a close partner of Adobe, Perficient Digital is working with Adobe to get up to speed with AEM as a Cloud Service. Expect to see a lot more posts and thought leadership on AEM as a Cloud Service coming from the team at Perficient Digital as we get ready for Adobe Summit 2020!

 

The post Thoughts on AEM as a Cloud Service appeared first on Perficient Digital.

AEM as a Cloud Service Followup: Insights from Cedric Huesler

$
0
0

 

Yesterday, Cedric Huesler, the Director of Product Management at Adobe started a Twitter thread on AEM as a Cloud Service. I have a number of burning questions about AEM as a Cloud Service, so I figured I’d take Cedric up on the offer to ask anything.

Cedric graciously replied, hopefully, you find these replies helpful as we all learn more about AEM as a Cloud Service:

 

Q1. What’s the plan for customers who do not want to run this in Adobe’s tenant?

A1. Today we are offering AEM as CS, MS and self-hosting. We have a single code base for all three.

Q2. What is the roadmap for AEM “Classic”?

A2. We will update SP schedule later this week.
A2 (part 2). SP schedule updated with 2020 dates: https://helpx.adobe.com/experience-manager/maintenance-releases-roadmap.html

@WimSymons – Not really an answer. Okay there will be extra SP’s and CFP’s, but the question is, will there any “classic” AEM major releases after 6.5 or will you put your money on AEM in the cloud only?
A2 (part 3). For 2020, we keep updating the single code base for the 3 deliverables and don’t see a need for a major release (to avoid efforts on customer-side to move up – SP are easier to install). If you are not yet on 6.5 – please do that 1st

Q3. What’s the underlying persistence mechanism? S3+Mongo?

A3. See Oak code-base – mongo and new segment blob store.

Q4. Is this running on Azure? AWS? Will customers be able to choose?
A4. It’s a mix – mostly azure today but can change anytime.

Q5. Will customers be able to choose what AZ’s to deploy their instances? Including China?
A5. Yes, today you can choose regions.

Q6. Will Customers be able to specify routing rules for requests based on the visitors origin?
A6. Yes, CDN is bundled in.

Q7. Can you temporarily skip / roll back releases if you encounter problems?
A7. Yes and No, the release validation process does that – automated.

Q8. How often will Adobe ship new releases and what will be the procedure to validate customer images?
A8. Daily, validation process is quite evolved. Will link up details later

Q9. What’s the index storage mechanism? SOLR?
A9. Today unchanged.

Q10. Is there a plan / timeline to port the remaining AEM apps (Screens, Forms) to AEM as a Cloud Service?
A10. Yes – this year.Huesler, Cedric (@keepthebyte). “1216857162405707777” 13 Jan 2020 Tweet.

 

Do you have your own questions about AEM as a Cloud Service? Ask Cedric yourself!

 

Additional Insights on AEM as a Cloud Service

 

A few of the underlying technologies which Cedric references or are useful to read:

 

Sling Feature Model

The new provisioning model for Apache Sling which is used to generate AEM as a Cloud Services instances by creating a “feature model” with the base AEM and customer code. You can also watch the 2019 AdaptTo seminar on the Sling Feature Model.

Oak BlobStore

The Oak Blob Store is the new persistence mechanism for large binary files. It splits the files into chunks, hashes each chunk and then stores each chunk into the segment store.

Deep Dive into Cloud Native AEM Deployments based on Kubernetes

Seminar from AdaptTo 2019 talking about Adobe’s deployment of AEM in Kubernetes (aka AEM as a Cloud Service).

Sling Content Distribution for the Cloud

Another seminar from AdaptTo 2019, talking about how Adobe uses Apache Kafka to orchestrate Content Distribution on AEM as a Cloud Service.

AEM as a Cloud Service User Guides

The starting point for Adobe’s documentation on AEM as a Cloud Service.

Getting Started with WKND

Adobe’s reference site WKND has been updated to be compatible with AEM as a Cloud Service.

 

The post AEM as a Cloud Service Followup: Insights from Cedric Huesler appeared first on Perficient Digital.

Adding Marketo Forms in AEM Pages

$
0
0

Adobe’s acquisition of Marketo brings exciting opportunities to extend Adobe’s considerable marketing capabilities with a tightly integrated B2B and ABM solution. As a leading partner of both Adobe and Marketo, Perficient is leading the push to integrate these solutions.

One of the main integration points between AEM and Marketo is via Marketo’s JavaScript forms. We built a component to integrate Marketo JavaScript forms into AEM and contributed it into ACS AEM Commons so now you can add Marketo forms into AEM pages as simply as adding and editing any other component.

 

See How Easy it is to Embed a Marketo Form

 

 

Installing the Marketo Form Embed AEM Component

The Marketo Form Embed Component is implemented as a AEM WCM Core Components Embed Embeddable and therefore requires the following dependencies:

Once you have installed the dependencies, you can use the Marketo Form Embed on any page you have enabled the Marketo Cloud Configuration.

Using the Marketo Form Embed AEM Component

The Marketo Form Embed AEM Component allows you to search and select from the forms available in Marketo. But the Marketo Form Embed can do far more than just embedding a form, you can set the redirect URL, set variables and even add custom scripts.

Read more on using the Marketo Form Embed on the ACS AEM Commons website.

 

The post Adding Marketo Forms in AEM Pages appeared first on Perficient Digital.

1st Party Adobe Launch with ACS AEM Commons

$
0
0

Adobe has supported CNAME configuration for Adobe Analytics and Adobe Target for some time now, but unfortunately doesn’t provide the same for Launch by Adobe. The latest version of ACS AEM Commons, version 4.4.0, includes a new feature to fetch remote files and serve them via AEM. The primary use case I implemented this feature for was to automatically download the Launch by Adobe script so it can be served from the primary domain.

Why do we need to serve Launch from our domain?

Protecting consumer privacy and providing an excellent consumer experience is a delicate balance. The confluence of Safari’s Intelligent Tracking Prevention, the widespread adoption of adblockers and Google Chrome’s coming blocking of third party cookies have limited Digital Marketer’s ability to optimize and personalize experiences as progressively they make it harder to effectively measure and optimize user interactions.

Research has shown, however, that the problem is not that consumers are blanket against personalization or even advertising but that they despise badly done advertising and personalization.

Types of Digital/Mobile Ads US Consumers Find Annoying, Jan 2019 - eMarketer

How do we as Digital Marketer’s deliver better ads and experiences? Again, based on market research, the major pain points for consumers are irrelevance and performance. Both of which we can address with the Adobe Experience Cloud suite of tools.

Performance is a full, separate discussion, so let’s focus on the basics we need to be able to create personalized, relevant experiences. With the Adobe Experience Cloud, this means having Adobe Analytics, Launch and Target working to effectively personalize our digital experiences. But how do we ensure that if AdBlockers or even the browser themselves can block the cookies we use or even the tools themselves?

 

CNAMEs with Analytics and Target

 

Adobe has an answer for Adobe Analytics and Adobe Target. Each tool supports setting up and serving the scripts from a CNAME record on your own domain. This changed the cookies from third to first party from the browser’s perspectives and bypasses the domain name lists in Ad Blockers. For more information read:

All of this is good, but if an Ad Blocker blocks adobedtm.com the Launch doesn’t fire and the whole thing falls apart.

Unfortunately, Adobe does not provide a CNAME’ing solution for Launch, so we have to either proxy or otherwise download the Launch script, which is where the new ACS AEM Commons feature comes in.

 

Syncing Launch into AEM with the ACS AEM Commons File Fetch

 

The File Fetch service is configured via OSGi, so work with development teams to configure the URL for the Launch script and the path within AEM Assets to save the file. Based on the configuration, the File Fetch service will fetch a file from a URL, load the file into AEM Assets as a dam:Asset and then replicate the asset. It uses the HTTP responses status and will not perform any updates if Launch returns a 304 status code so it will only update when needed.

Since the Launch script is automatically replicated on update, you should not need further Dispatcher cache configuration, however you should ensure that the client-side cache headers will not cache the Launch script.

File Fetch Configuration

From there, include the Launch script from AEM Assets via the path like you would for any other Launch script and to browsers and visitors, Adobe Analytics, Launch by Adobe and Adobe Target are all indistinguishable from any other scripts on the website.

The post 1st Party Adobe Launch with ACS AEM Commons appeared first on Perficient Digital.

Viewing all 49 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>