Working with url interceptor/servlet filters in Crafter CMS

A filter in Crafter is a Groovy-based controller that allows you to intercept inbound requests for content and API responses and dynamically apply rules, modify the request or transform the response.  A Crafter Filter has the same interface and mechanics as a Java J2EE Servlet Filter.  Some examples of filter use are:

  • Apply security rules: Check for SAML2, Site Minder or other security tokens before allowing the request to proceed.
  • Active Record: Example: before serving the requested resource, look up and load the user’s profile into the request so it is available to all components of the system.
  • Apply compression: Gzip all of the data returned by the requested resource (page, API, etc)

In this article, we’ll learn the specific mechanics of creating and configuring a filter in Crafter CMS.

Step 1: Create the controller

Let’s start simple.  We’ll create a controller that prints a message before processing the request (or subsequent filters in the chain) and a message after control is returned to the filter.

Here’s the code.

 logger.info("Handling the request")

filterChain.doFilter(request, response)

logger.info("Control returned to filter/controller")

Yep, that’s it!  It’s that simple. The key is that you can put code before and after doFilter.  That code can do just about anything.  Typically it’s actions like inspecting the request and making decisions, modifying the request for further downstream processing wrapping the response object.

Step 2: Install the filter in the CMS

Now let’s install the controller into the CMS/project.  With developer or user role your CMS sidebar should contain a folder called scripts:

2.1:  Right-click on the scripts folder and click “Create Folder.”  Enter “filters” as the folder name.

2.2: Right-click on the new filters folder and click “Create Controller”  Enter “MyFilter” as the name and click “Create”

2.3 Add the code from above and click “Update.”

At this point, you should see your filter in the Sidebar and we’re ready to configure it to run when a user requests a resource.

 

Step 3: Configure the filter to execute

Now we need to tell the filter which resources to execute for by configuring the order of execution, the URL resource patterns it should execute on and the request method types that it should apply to.  To do this we modify the Crafter Engine /Config/site.xml

3.1 Add the following filters tags to your site.xml.  This will run your filter on every kind of request for all URLs.

<?xml version="1.0" encoding="UTF-8"?>
<site>
    <filters>
        <filter>
            <script>/scripts/filters/MyFilter.groovy</script>
            <mapping>
                <include>/**</include>
            </mapping>
        </filter>
    </filters>
</site>

Once the Engine config is updated we have to tell Crafter Engine to reload it. To do this execute this simple API: http://localhost:8080/studio/preview/#/?page=/api/1/site/context/rebuild.json

Step 4: Test

Since our simple example prints messages into the log, you will need to “watch” your log files. The log is located at INSTALL_DIRECTORY/logs/tomcat/catalina.out.

4.1: In the console, watch the logs by printing it out in as it is appended:

tail -f ./logs/tomcat/catalina.out

4.2: Simply reload a page: http://localhost:8080/studio/preview/#/?page=/

4.3: You should see your log entries in the log file every time you view a page or access any other resource.

Create Spring Beans in Your Site with Crafter CMS

Crafter CMS supports scripting in Groovy.  It’s awesome.  It’s lightweight. It’s fast. It’s easy.  That said when solutions start to become more sophisticated developers need ways to manage the complexity.  Spring bean factory is an inversion of control implementation that has become a standard for wiring components of a system together.  Crafter CMS lets you create classes in Groovy and wire them together as spring beans that can be used by other scripts in the system.

Step 1: Create your classes

Put your classes under scripts/classes/groovy
I.E., scripts/classes/groovy/mysite/AddressBook.groovy

Note: In older versions of Crafter (2.5.x) The path for classes is outside of the scripts folder.  For these older versions, the path is: classes/groovy/YOUR_PACKAGE/YOUR_CLASS.groovy

package mysite

import java.util.Map

public class AddressBook {

   def addresses  // map
   def label

   public int getAddressCount() {
      return addresses.size() 
   }
}

Step 2: Wire your Spring beans

Place your Spring bean configuration at the following path:

config/spring/application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


  <bean id="myAddressStoreMap" class="java.util.HashMap">
  </bean>
 
  <bean id="myAddressBook" class="fastenal.AddressBook">
    <property name="label" value="Russ's Address Book" />
    <property name="addresses">
      <ref bean="myAddressStoreMap" /> 
      </property>
 </bean>
</beans>

Step 3: In a Controller, get a hold of the bean and use it

templateModel.addressBook = applicationContext.get("myAddressBook")

Step 3.a Show the count in a template

<h1>Address Book: ${addressBook.label}</h1>
<h2>Entries: ${addressBook.addressCount}</h2>

Match Highlighting for Search in Crafter CMS

Highlighting search terms in search results is a common requirement for many websites.  Crafter CMS builds on top of Apache Solr and make implementing rich search and other query-driven experiences super simple.

In this tutorial, we’ll create a simple article search backend that highlights the search terms that were used within the results returned to the user.

Step 0: Prerequisites

If you haven’t gotten Crafter CMS set up and built your first site you can follow this tutorial to get started: Working with Your First Crafter CMS Web site.

Step 1: Build a content model for articles

The next thing we need is content to query against.  The first step in supporting content creation is defining the Content Type.  The Content type is the definition of the structure of a particular type of content.  In our example, we want to define the structure of an Article.

A simple article should have:

  • A Url
  • A title
  • An author name
  • A body

To define this we use Crafter’s Content Type management console:  Below you can see the example model including the fields and their types.

You can learn more about content modeling here Content Modeling in Crafter CMS.

Step 2: Create content

Now that you have your article content type defined you can create articles.  To create an article open the pages folder (we modeled the article as a page with a URL) in the sidebar and right click on the home page:

Step 3: Create a REST script to return highlighted results

Now that you have content you can write a RESTful controller and test it.  Let’s create a simple GET based REST controller.

  1. Open the Sidebar and locate the Scripts folder.
  2. Open the Scripts folder and navigate to “rest” folder.
  3. Right click on it and choose “Create Controler
  4. In the script name dialog, enter “search.get” and click Create.
  5. Enter the following code:
// build a query
def keyword = params.q 
def queryStatement = "content-type:\"/page/article\" " 
 
 if(keyword) {
      queryStatement += " AND $keyword"
 }
 
 def query = searchService.createQuery()
 query.setQuery(queryStatement)
 query.addParam("hl", "true")
 query.addParam("hl.fl", "body_html")
 query.addParam("hl.simple.pre", "<b>")
 query.addParam("hl.simple.post", "</b>")
 
 // execute the query
 def executedQuery = searchService.search(query)

def matches = [:]
matches.found = executedQuery.response.numFound
matches.articles = executedQuery.response.documents
matches.highlights = executedQuery.highlighting

return matches

Step 4: Execute the Script

In a browser, go to http://SERVER:PORT/api/search.json?q=AWORDTHATEXISTSINRESULTS

example: http://localhost:8080/api/search.json?q=bacon

Work Your Own Way with Crafter CMS (Series Part 1): Step-through Debugging

Most CMS platforms do a decent job of simplifying content and digital experience creation and editing for non-technical content managers.  The challenges really start once you need to innovate and development is required.  Traditionally CMS platforms have been pretty bad for developers.  They require a lot of CMS specific knowledge and don’t integrate with developer tools and process.
Here are 7 things that developers really want with a CMS:

  1. Let me work locally with my own tools like my IDE and my source code management
  2. Let me leverage my existing skills.  I want a low learning curve. Don’t make me learn a new, niche framework
  3. Let me work in teams on multiple projects at the same time without interfering
  4. Let me maintain a real development process
  5. Make the integration with the CMS seamless
  6. Don’t make me do builds
  7. Don’t make me do heavy deployments

In this installment of the Work Your Way Series we’re going to tackle item #1 (Let me work locally with my own tools like my IDE and my source code management.)   Let’s start with some background: Crafter CMS uses Git as its primary content store.  That’s the foundation of the solution for developer desire #1. A developer can mount a local clone of a Crafter CMS project directly with their IntelliJ, Netbeans, Eclipse or other IDE.  That means they can use their preferred development tools to edit and debug code and templates.  And as they work, all of the changes they make are tracked by the Crafter CMS via its native Git support.  Sounds awesome right?  Let’s learn how to get set up:

Step 1: Get a local copy of Crafter CMS running

You are going to use your IDE to update and debug your code and templates.  You’ll want a local instance of Crafter CMS running so you to execute the code and attach your debugger to.

To install and get Crafter CMS running (authoring environment) locally follow this guide:
http://docs.craftercms.org/en/3.0/getting-started/quick-start-guide.html

Step 2: Start a Crafter CMS project

Now that Crafter CMS is up and running let’s create a project so we have a place to work.  We’ll create a local project for the sake of this article, however, as we’ll learn later in this series, it’s possible to clone a remotely managed project as well.

To create your CMS project follow this guide:
http://docs.craftercms.org/en/3.0/getting-started/your-first-website.html

Step 3: Mount your IDE on top of your Crafter CMS project

For this article, I’m going to use IntelliJ.  Any IDE that allows you to connect to a remote JVM via Java Debug Wire Protocol (JDWP) should work.  Eclipse and Netbeans are other solid IDE options.

  1. Within IntelliJ, create a new project:

  • Select Create New Project

 

  • Choose Groovy

  • A: Configure your project name to something you like
  • B: Browse to the Git repo “Sandbox” under your “CRAFTER-INSTALL/data/repos/sites/PROJECTID/sandbox”
  • C: Change the module name from Sandbox to your project name

 

  • Once your project is created, open it to see all the files.  IntelliJ automatically recognizes you are sitting on top of a Git repo and will allow you to do Git operations right from the IDE.
  • Note that a Groovy project creates an “src” folder.  You can delete this.  You don’t need it.

  • Right click on your model and add a new file called “.gitignore”
  • Do not add this file to Git when prompted.

The contents of the .gitingore file should be as follows:

*.iml
.gitignore
.idea/*
  • This will tell Git and Crafter CMS to ignore your IDE project files

  • If you were to run a “git status” command in your project sandbox you would note that Git is totally satisfied and ready to rock 🙂

 

Step 4: Set up step-through debugging

Great, now that we’ve got our IDE sitting on top of our project and we’ve got the Git integration configured we’re ready to set up the step through-debugging.

  • Shut down Crafter CMS
  • Add the following lines to CRAFTER-INSTALL/bin/apache-tomcat/bin/setenv.sh (or setenv.bat)
    • Syntax in .bat will be slighly different

export CATALINA_OPTS="$CATALINA_OPTS -agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n"
  • Start Crafter CMS

Back in our IDE we can now configure and start our remote debugging session!

  • Go to “Run” and select “Debug”

  • Since this is a new project we’ve got to configure our debugging connection.  The next time you click Debug you’ll just select the existing configuration and click Run.

  • Click the + (plus) icon to create a new configuration
  • Select “Remote”

  • Give the debug configuration a name
  • Change the port from 5005 to 8000 (to match the value in setenv.sh)
  • Click “Apply” to accept the changes
  • Click “Run” to attach to the JVM running Crafter CMS

  • Congrats! If your JVM configuration is correct and your ports match in the debug config when you click “Run” you’ll see the “Connected” message in the console as shown above.

Step 5: Start debugging

Now that we’re connected we can start stepping through code in our Groovy Scripts.

  • Open the “Scripts” folder in your project
  • Browse down through classes, org, craftercms, sites, editorial and open SearchHelper.groovy
  • Set a breakpoint at line 56.  This method is used by the Home Page controller of the editorial website we created in step 2.
  • In a browser, open the Crafter CMS preview for the homepage of the website we created

  • When you load the homepage in Crafter Studio the rendering will pause

  • IntelliJ’s window will typically come to the foreground automatically.
  • The thread has been paused and the IDE is now in control of the thread execution.
  • You can now use the step-through debugging tools in the IDE to walk through the code.

Step 6: Magic

Found a bug?  Here’s where things get really fun.  We’re about to see the benefit of bringing Git, Groovy and your IDE together in one place.  Fixing the bug and sharing that fix with the rest of your team is a breeze:

  1. Once you understand the bug and you know what code you want to change, click Play to let the thread complete.
  2. Using the IDE, fix the Groovy code.
  3. Simply refresh the browser again to test.  Step through and verify things are working.
  4. Using the IDE to interface with Git, commit the code and push the code forward in your team mates.
  5. Find something fun to do or work on.  You have a lot more time on your hands now that you are working in a truly integrated, no-compile required, easy to code and debug CMS 🙂

 

 

Get the Names of Sites Running in Crafter Engine and Return it them as JSON

From time to time developers want to be able to get a list of tenants on a given Crafter Engine.  A tenant is equivalent to a project in Crafter.  That project may be a website, a content app, a headless content API or any one of 1000 different kinds of digital experience.  Usually, when people want to get a list of the active tenants on a server it’s to assist with some kind of DevOps automation of site creation and management.  In this example, we create a simple RESTful service that returns the list of sites running in Crafter Engine. You can find the API for the Context Manager HERE

Step 1: Create a REST Controller

  • In a Crafter Studio project, Under Scripts/rest right click and click “create controller.”
    • Enter “get-sites.get” as the controller name
  • Add the following code to the controller.
def siteContextManager = applicationContext["crafter.siteContextManager"]
def siteContextList = siteContextManager.listContexts()
def siteNames = []

siteContextList.each { siteContext ->
    def name = siteContext.getSiteName()
    siteNames.add(name)
}

return siteNames

Step 2: Execute the Service

Working with Content as XML/DOM in Crafter CMS

In a previous article (Querying Content in Crafter CMS) we talked about how you can query content in Crafter using content and search services. Under the hood, Crafter CMS saves all of the content you create through the authoring interface (Crafter Studio) as XML.  This XML is published from Crafter Studio to dynamic delivery engines (Crafter Engine) and is available through the content services and is also indexed in Solr and thus available through Crafter’s search services.  There are times in the rendering engine (Crafter Engine) when you may want to get access to values in the XML directly and work with the content as an XML Document Object Model (DOM) API.

In the example below I will show you how you can:

  1. Load a content object
  2. Get access to its DOM
  3. Query for DOM elements within the parent object
  4. Process the results

To illustrate this let’s imagine that we have a use case where content authors need to manage values like CEO name or Number of Offices throughout a site that might change.  They want to pepper these values throughout the site but want to update them quickly from a single place.    To do this we would use a macro/placeholder type approach in the content where the author would enter content with macro/placeholder in the place where the value should go.

Example:

Acme Anvil Co has [Office_count] offices throughout the world.

To manage the Macro/Value pairs we’ll give the authors a content type:

Once you have your macro type defined you can create a content object based on that type:

Now that we have created an author managed list of macros and their corresponding values.  Let’s create a basic controller (some assumptions to keep things simple) to process the content in a component and replace the macros found in the content with the value.

Controller example:

// Load the content object containing the macros key values
def macroItem = siteItemService.getSiteItem("/site/components/5ef8d326-3e85-9f67-e8d6-47fb5dfba21d.xml")

// Get the unprocessed content
// Here we'll put some assumptions in the code.  In reality you may want 
// to process all the content fields in the content.
def content = contentModel.queryValue("content_html")
def contentUpdate = content
// Query the macros and iterate over them performing the replace. 
// this is where we get the DOM and leverage the DOM API
def macros = macroItem.getDom().selectNodes("//item")
macros.each { pair ->
 def macro = pair.valueOf("./macro")
 def value = pair.valueOf("./value")
 contentUpdate = contentUpdate.replace("["+macro+"]", value)
}

// Make the processed content available to the template
templateModel.content_html = contentUpdate

 

You can easily tie this controller into any template by adding it to the top of the template:

<@controller path="/scripts/controllers/macro-controller.groovy" />

Most of the time with Crafter CMS, there is no reason to access the DOM directly.  From time to time you may find it more convenient or necessary.  Now you know how!

Working with Your First Crafter CMS Website

This article assumes that you have followed the steps in the Cafter CMS Quick Start Guide to get Crafter CMS installed and logged in to Crafter Studio. We will be using an out-of-the-box blueprint, called “Website_Editorial” to create your first website.

Let’s get started building your first website!

Creating your website from out of the box blueprint Website_Editorial

After logging in, you’ll see the MySites screen (Below). Click on Create Site

Your First Website - Sites ScreenGive the site a friendly name for the Site Id , a description and then choose a blueprint. We’re going to be using the “Website_Editorial” blueprint. Blueprints offer you a starting point for your website. New blueprints can be created and installed into the system. As you are entering the site id, spaces are removed and upper case letters are converted to lower case letters.

Your First Website - Create a SiteClick on Create and wait for the system to create your site based on the blueprint. It’s creating the following: configuration, site content, and permissions based on the template provided by the blueprint.

Your First Website - Creating a Site Spinner DialogWhen it’s done you will be taken to the Home Page of your site: (need to update image below)

Your First Website - Home PageYour site is setup, we can now start adding/editing content! To edit content you see on the page, click on Edit at the top (see above). This will open a form (see below) where you can edit the page content. To see other ways of editing page content, see Editing a Page.

Your First Website - Editing Content

Adding a new article page to the site

We’ll be adding a new article to the site. To add a new article (or a new page), navigate to the level and location within the site navigation tree in the Sidebar where we want to create the new page. In this case, we are adding an article under articles -> 2017 -> 3. Right click, then select New Content (need to update image below)

Your First Website - New ContentWe’ll then select the page template we want. Since we are adding a new article to the site, we will be selecting the template Page – Article

Your First Website - Select Page TemplateWe’ll start filling out the form for our new article, “Where to find cherry blossoms in Virginia”. For the Page URL, replace spaces with dashes. You can write the Internal Name and Title however you like as long as it is 50 characters or less as indicated on the right of the input boxes. For the Headerand Sidebar, we will be using the default provided by the template.

Your First Website - Page PropertiesThe next section on the form is the Metadata section, where we can select the category for our article, the targeted segments of the article and whether our new article should be added to the Featured section. Our new article, will be under Entertainment for the Categories and the targeted segments is Gal. We will also be placing our new article in the Featured section.

Your First Website - Page Metadata SectionFinally, we add our blurb in the Content section of the form. Here, we fill out the SubjectAuthorDateSummaryImage and Section, which contains the content of our article.

Your First Website - Page Content SectionHere’s the site, with our newly created article in the featured section.

Your First Website - Newly Created Site Home PageYou can add more pages or modify/remove the existing pages from the blueprint, depending on your needs. To remove or edit an existing page, navigate to the location of the article you want to edit/remove. Right click on it, then select the action you would like to do on the page.

Your First Website - Edit a Page

Updating the Contact Us section in the sidebar

Another thing that we may want to modify from the blueprint, is the left rail. For this example, we are going to modify the Contact Us section in the left rail (contact widget). To edit items in the sidebar, click on the pencil on the top right of your screen to enable in-context editing. Pencils should appear on sections editable on the page. Go to the top left of the left rail and click on the pencil there.

Your First Website - Edit the Left RailA form with all the editable content of the left rail will appear. Go to the Widgets section of the form, select Contact Widget and then click on the Edit button on the right of the list of widgets.

Your First Website - Left Rail FormA form containing all the editable fields in the Contact Us section will appear. Modify the fields that you want to change.

Your First Website - Contact WidgetHere’s the sidebar with the Contact Us section updated.

Your First Website - Updated Contact Us Section

Editing the features section, “Erat lacinia”

We will now edit the features section in our blueprint. The features in this section has been configured as components, as you will see in the images below. There are multiple ways of editing the features section in the blueprint.

Your First Website - Add Features through Drag and DropWe’ll start out by adding a feature using the pencil at the top of the features section (In the image above, we will use the pencil captioned “Edit the whole features section”). Click on the pencil at the top of the features section. A form will open containing the content of the section. As you can see in the image below, there are currently two features in the section.

Your First Website - Edit by Clicking on the PencilIn this form, you can add another feature, by clicking on the Add button, which will give you a menu to Create New – Features or Browse for Existing – features

We will add a feature by selecting Create New – Features as seen on the image above. This will open a form, where we will now enter our content.

Your First Website - New FeatureYour First Website - New Feature AddedWe will now add another feature, by selecting Browse for Existing – Features, after clicking on the Add button. This will bring up a form containing a list of existing features in the blueprint. Select one, then click on Add & Close or, click on the radio button of your selection, then click on Add Selection. This will add your selected existing feature to the features section of the page.

Your First Website - Browse for Existing Features ComponentWe will again add another feature, this time by opening the Preview Tools panel, and then clicking on Page Components. A Components panel will open where the Preview Tools panel used to be, containing components that you can drag and drop onto the drop zone highlighted on the page. To click and drag a new feature onto the drop zone, click and drag Feature, under the general heading. This will then open up a form for you to add your new feature content. To click and drag an existing feature onto the drop zone, click on Browse Features. This will then open up a form containing a list of existing features that you may choose from. Make your selection, the form with the list will then close and now you can drag and drop your selected existing feature onto the drop zone.

Your First Website - Drag and Drop ZoneFrom inside the drop zone, you may also re-arrange the features by clicking and dragging on a feature and placing it in your desired position. Notice the positioning of the newly added feature and the existing features, which have been re-arranged compared to the previous image. To delete/remove a feature from the drop zone, just click on the X as show in the image below.

Your First Website - Drag and DropTo edit a feature, select a feature from the list and click on the Edit button on the right of the list. Edit the fields you would like to modify, then click on Save and Close or Save Draft to save your changes or click on Cancel to discard all changes in the form. You can also edit a feature by clicking on the pencil next to the feature when In-Context Editing is enabled.

Your First Website - Edit FeatureTo remove a feature, select a feature from the list and click on the X button on the right of the list. Or, from the drag and drop zone when you click on “Page Components” in the Preview Tools panel, click on the X next to the feature.

Your First Website - Remove Feature

Publishing Your New/Edited Page

Your site is published after creating the site from the Website_Editorial blueprint. If you make edits to any of the pages or created new pages, it will need to be published for your site visitors to see the changes. There are a couple of ways to publish your page edits. The first thing you need to do is to navigate to the page you want to publish in the Site Navigation Tree (Enabled by clicking on Sidebar on the right of the Crafter CMS logo on the upper left hand corner of Studio). After navigating to the page you want to publish, there are two ways to publish:

  • Click on the page you want to publish. In the context menu, click on Approve & Publish
  • Right click on the page you want to publish from the Site Navigation Tree, then click on Approve & Publish

Your First Website - Publish Your New ContentYou will then prompted whether you want to publish the page now (Items should go live now), or publish the page at a later date and time (Items go live on a specific date & time).

Your First Website - Publish OptionsFor more information on content authoring, please see the documentation section: Content Authoring

Great Crafter CMS Webinars

Check out these free pre-recorded online events! Learn more about how Crafter CMS is built and where and how to apply it to your projects!

 

Planning a Smart Mobile App Development Strategy

Building and Running Crafter CMS from Source. It’s Simple!

Crafter CMS is an open source content management system for Web sites, mobile apps, VR and more. You can learn more about Crafter here.  In this article you will learn how to build Crafter CMS from source as well as how to start and stop the services.  It’s very easy!  Thanks to Gradle and a very easy install process, you will be up and running in 3 simple command line operations!

0. Prerequisites

You must have these prerequisites on your system before you begin:

  • Java 8
  • Git 2.x+
  • Maven 3.3.x+

OS X extra prerequisite

  • If you’re on OS X, then using brew install the latest openssl formula, like this: brew install openssl

1. Clone the Crafter repository

git clone https://github.com/craftercms/craftercms.git

This will create a directory called craftercms.  Change path in to this directory.

2. Build the Environment

Crafter CMS is built along a microservices architecture, and as such, comprises a number of head-less, RESTful, modules that work together to provide the final solution. In this section, we’ll start with the simple case of build everything/run everything, and then move on to building/hacking individual modules.

Build all Crafter CMS modules:

    ./gradlew init build deploy

3. Start and Stop All Services

Start Crafter CMS:

   ./gradlew start

You can now point your browser to http://localhost:8080/studio and start using Crafter CMS. To get started with your first Crafter CMS experience, you can follow this guide: http://docs.craftercms.org/en/latest/content-authors/index.html.

Note
  • The authoring environment runs on port 8080, a great place to start, while the delivery environment runs on port9080.

Stop Crafter CMS:

    ./gradlew stop

Two Environments: Authoring vs Delivery

You might have noticed that you essentially have two environments built and running: authoring and delivery. Crafter CMS is a decoupled CMS, and that means you have an authoring environment that caters to content creators, and a different environment, delivery, that handles the end-users that use the experience created by the former.

As a developer, you can use an authoring environment for most tasks without the need to run a delivery environment. It’s important to note that delivery essentially runs the same software that’s in authoring except Crafter Studio (the authoring tools). By default, this project will build both environments unless instructed otherwise.

The authoring environment runs at http://localhost:8080/studio, whereas

the delivery environment runs at http://localhost:9080/

Start, and Stop a Specific Environment

To start and stop one of the two environments is similar to building/starting/stopping All.

Authoring

    ./gradlew start -Penv=authoring
    ./gradlew stop -Penv=authoring

Delivery

    ./gradlew start -Penv=delivery
    ./gradlew stop -Penv=delivery

Ready to Rock

In just a few command lines and a few minutes you are now ready to rock!  Use Crafter Studio to create new projects or alter and build the source code to make changes to the platform itself!  Happy crafting!

Why Developers Should Care About CMS

As developers, we’ve got a strong handle on how to manage and deploy our code assets.  Yet every one of us, at some point in our application build has said, “What about this text? What about these images? Where do these belong?”  That’s pretty universal.  Nearly every single application today has content in it.  Be it a web app or a native app; it’s full of strings, images, icons, media and other classes of content.

This content doesn’t really belong in our code base — because it’s not code.  These non-code assets make us as developers pretty uneasy.  We know that at some point a business user is going to ask us to make a change to one of those strings and we’re going to spend hours of build and deploy cycles to handle a 30-second code change.  We know that at some point we’re going to need to translate that content.  We know at some point we’re going to replace this UI with another one.   We know all these things  — and we know leaving that content, even if it’s abstracted into a string table or a resource bundle is going to come back to haunt us; no matter the abstraction: it’s part of the build, developers need to update it.  Developers and Systems folks need to deploy it.  

Smart developers separate code from content.  They make sure that the content in the application is completely independent of the build and deploy cycle of the application itself.  Where appropriate they make sure non-technical business users and have access to the externalized content and can update it and publish changes at any time.

Consider the following scenario:  Your application is for an insurance company.  Along comes major regulation change.  Now your (and every other application) needs to change its language accordingly.  If the content was separate from the application the response time and cost to make changes is minimal.  It’s business as usual.  If the content is not separate you are looking at months of builds, testing and deployment that costs time, opportunity and a tremendous amount of money,

What we’re really talking about is application architecture.  Making the right decisions has significant impacts on our development teams and process and as we’ve illustrated, our organization’s responsiveness and bottom lines.

Solving the Content Problem Through Application Architecture

This problem is very similar to another problem:  Websites.  Waaaaaaaaaaaaay back in the 1990’s people built and maintained entire websites in HTML by hand.  You had to be a programmer who understood the markup and how to update it and ultimately deploy it to a server once complete.  This model didn’t work. Once business started using the web to communicate to the masses marketing departments started getting involved.  Marketers wanted constant updates. Developers wanted to write code, not update copy.  They needed a solution.  The Web Content Management System (WCM for short) was born.  WCM offered a new architectural solution to manage websites. WCM allowed the developers to put the code into templates that contained placeholders for the content and gave authors a user interface to manage and edit the content at any time.  The content is managed separately from the code (the templates) and the two are brought together to create the final product. Everyone wins.

We need the same capabilities that WCM provides but for our applications.

Why Not Use a Traditional CMS?!

Simple.  Traditional CMS platforms have the wrong underlying design. Most CMS platforms were built or are based on the same design as CMS’s that were built 20 years ago.

  • They were built to manage pages:  Most CMSs do not have a generic concept of what content is.   These systems were built to manage pages.  You might be able to contort the system to get what you want from it but it will be a hack. You need a CMS that is agnostic to the kind or type of content you need to manage.
  • They rely on the wrong type of data tier: RDBMS/SQL databases were the primary backends for data regardless of the problem and open source options like MySQL were readily available.  You need a CMS that leverages a data tier that is more distributed and flexible.
  • They are built on the wrong technology: Many CMS platforms are built in PHP.  That’s fine for certain use cases. But frankly, Java has a larger community, more library support and a lot of powerful platforms like Solr, Elastic Search, Hadoop (and many others) that plug into a Java CMS perfectly.  Why run multiple tech stacks to accomplish a single goal?
  • They aren’t secure: Most CMS platforms couple authoring and delivery together in a single database.  That means work in progress (like pending policy updates) is available in the delivery runtime to anyone who finds a way into the database.  That can spell disaster in the event of a hack. Large companies and governments have suffered expensive and dangerous leaks due to this kind of coupled, insecure architecture.
  • They don’t support multi-tenancy: Most of the CMS platforms out there are not multi-tenant.  If you’re going to back apps with a CMS you need a CMS that will let you properly segregate and secure content between apps.  No one wants to do a CMS install PER app.
  • They don’t scale:  RDBMS is hard to scale.  You either cluster or replicate.  Both have serious issues when it comes to really large, global and auto-scale type deployments.  Supporting an app with your CMS will demand scale. Design for scale from the start.
  • They don’t fit into your development tools and process: When most CMS platforms were designed the content authors were the only audience that mattered.  Today it’s different.  Developer tasks like managing templates, CSS, JavaScript, content models and other artifacts need to be just as easy — and it needs to fit in with your existing workflow.  That means Git source code management, Continous Integration (CI), Integration with your IDE, the ability to fork and support multiple teams simultaneously.

If Not Traditional CMS, Then What? A Modern CMS, That’s What!

To get different results you need a different design.  You need a modern CMS:

  1. Built with the right technologies like Java, Spring, Groovy, Solr, Git.  These are the technologies that will be easy to hire for, will fit into and integrate with any enterprise and will have the out of the box capabilities and horsepower to back any scale deployment.
  2. Decoupled architecture that cleanly separates authoring and content delivery responsibilities on to separate, independently highly securable, highly scalable infrastructures by a publishing process.  Decoupled Architectures don’t have work in progress outside the firewall.  They are much easier to scale.
  3. Built on scalable document-oriented data tiers like XML+disk/Git and Casandra and others.  Disk-based tech is much better for streaming rich content and support global distribution better because they don’t need to be clustered.  At a minimum, you want something that’s document oriented and that distributes globally better than a than a SQL backend RDBMS.
  4. Content type agnostic:  From strings to web pages, to videos and virtual reality experiences.  The CMS needs to accept any kind of content.  That comes down to how content is modeled and how it’s stored.  Does the CMS store content in a SQL database or a JCR repo?  Red flag.  Can’t provide Headless Content / APIs AND rendered content?  Another Red Flag.
  5. Is Multi-Tenant. You need to be able to support many customers/apps on a single install. Either you support it or you don’t and today it’s a must!
  6. Supports authors AS WELL AS developers and DevOps. Developers don’t want to work in some clunky CMS.  They want to work locally in an IDE, then be able to work with their team and ultimately go through the entire workflow out to production.  A modern CMS gives them this.
  7. Open Source.  Open is better than closed. The debate is over. Is it a must?  No. But you’ll get more for your money and you’ll get a lot more innovation at a faster rate if you leverage open source.

Where can I find a Modern CMS?!

Check out Crafter CMS!  Crafter CMS is a modern, 100% open source Java based CMS built on Git!  It’s easy for authors, Amazing for developers and Awesome for DevOps!  Crafter doesn’t sit on a SQL database or a JCR repo like so many CMS platforms out there.  It’s built on Git, Java/Spring, and Solr.  It brings the power Git to CMS!  Authors have true versioning.  Developers and DevOps can work they way they are used to, with the tools they are used to based on the technologies they already know.  Crafter CMS is 100% content type agnostic, highly secure, high performance and scales like nothing else.  If you’re building any kind of application or digital experience, you have content, and you NEED Crafter CMS.  Great experiences are crafted!