New Video: Made Easy with CoreMedia: B2B Digital Experience

B2B digital experience made easy! With our connectors into the eCommerce platform, CoreMedia enables editors to create custom digital experiences for their B2B partners. B2C and B2B are the same, shouldn’t your digital experience platform give you the same capabilities regardless of your business model? See how your B2B sites can be iconic with CoreMedia Studio.

Advertisements

Demo Jam: Being iconic and the future of digital experience

We at CoreMedia pride ourselves with our innovation and our ability to consistently deliver amazing capabilities that save marketers, editors, and merchandizers thousands of hours per year. Our path forward is to support all digital channels, including digital signage inside and outside of the store and even virtual reality, yes, virtual reality.

Take a look at this quick Demo Jam where I show our amazing booth at DMEXCO 2019 and also some of our cool extensions for virtual reality.

Personalization with Salesforce Marketing Cloud Journeys

In my latest Made Easy with CoreMedia video I show our new integration with Salesforce Marketing Cloud Journeys. In case you are not familiar with Journeys, take a look:

Salesforce Journey Builder is a feature of the company’s Marketing Cloud that manages the customer life cycle: the progression of steps a customer goes through when considering, purchasing, using and maintaining loyalty to a brand

searchcustomerexperience.techtarget.com

In this demonstration I show how you can personalize content to customers in various Marketing Cloud Journeys. This is great for extreme personlizations like abandoned cart content, birthdays and anniversaries, and much much more.

In this video I show how we use a Birthday Journey with a coupon banner to show to a user who is part of the “Birthday Journey with Coupon” journey.

We also show how you can use the CoreMedia studio to easily control multiple personalized banners for several different journeys. Putting this powerful personalization capability in the hand of editors with zero programming… awesome.

The best CMS for B2B Commerce!

I can hands down say we are the best CMS for B2B commerce. Our studio supports B2B Contracts for catalog filtering and pricing, giving the editors a seamlessly integrated environment between digital experience and B2B Commerce. Being able to do everything the cool fashion brands do can now be done in the B2B space with CoreMedia. You no longer have to suffer with sub-par digital experiences for your B2B partners doing business with you. You won’t get that newly hired millenial complaining your B2B system looks like something out of the 1990’s.

In my last Demo Jam I tackled some good old B2B use cases. Imagine completely taking over control of your digital experience with little to no IT involvement. So of course, this is a first in a series, so stay tuned and subscribe to my channel!

I am really interested in helping you out but I also want to know who you are, if you want me to know who you are open the LinkedIn point drive link below to watch my three minute video explaining what you can do with CoreMedia Studio in a B2B context.

Click here to watch the video!

Otherwise, if you would rather me not know who you were, feel free to still watch it over on YouTube – click here.

So either way, I welcome you to watch the video and see what you think. We will be at B2B Next in Chicago at the end of the month. Hit me up for a demo time slot!

CoreMedia Demo Jam 4 – HCL B2B Commerce

This demo jam shows how you can use the same CoreMedia Studio functions you use on a B2C site but in a B2B context featuring HCL B2B Commerce and the Aurora B2B Store.

Make sure you come see HCL B2B Commerce at B2B.Next in Chicago next month. I will be there and I would love to show you how well CoreMedia does B2B. Make sure you come to Booth 604 and see the HCL Commerce with CoreMedia demo!

When should I use Apache Druid?

I started having some good side discussions about Druid and the most common question was “when should I use Druid?”. The good news is the Druid documentation under the
Latest Design answers this question directly:

Druid is likely a good choice if your use case fits a few of the following descriptors:

  • Insert rates are very high, but updates are less common.
  • Most of your queries are aggregation and reporting queries (“group by” queries). You may also have searching and scanning queries.
  • You are targeting query latencies of 100ms to a few seconds.
  • Your data has a time component (Druid includes optimizations and design choices specifically related to time).
  • You may have more than one table, but each query hits just one big distributed table. Queries may potentially hit more than one smaller “lookup” table.
  • You have high cardinality data columns (e.g. URLs, user IDs) and need fast counting and ranking over them.
  • You want to load data from Kafka, HDFS, flat files, or object storage like Amazon S3.

Obviously event based data works very well with Druid, this is why I believe orders are a really good match for this. Because you can tie three critical pieces together for each order: SKU, Customer data, and Shipping, it becomes very easy to execute all kinds of queries tieing these data points together.

While I am somewhat stuck on eCommerce, here is a list of other companies that also use Druid for very different use cases (link).  Here are a few of my favorites:

Airbnb – Druid powers slice and dice analytics on both historical and realtime-time metrics. It significantly reduces latency of analytic queries and help people to get insights more interactively.

eBay – eBay uses Druid to aggregate multiple data streams for real-time user behavior analytics by ingesting up at a very high rate(over 100,000 events/sec), with the ability to query or aggregate data by any random combination of dimensions, and support over 100 concurrent queries without impacting ingest rate and query latencies.

Hulu – At Hulu, we use Druid to power our analytics platform that enables us to interactively deep dive into the behaviors of our users and applications in real-time.

Monetate – Druid is a critical component in Monetate’s personalization platform, where it acts as the serving layer of a lambda architecture. As such, Druid powers numerous real-time dashboards that provide marketers valuable insights into campaign performance and customer behavior

Nielsen – Nielsen Marketing Cloud uses Druid as it’s core real-time analytics tool to help its clients monitor, test and improve its audience targeting capabilities. With Druid, Nielsen provides its clients with in-depth consumer insights leveraging world-class Nielsen audience data.

The original list is pretty large, it is fairly safe to say Druid has a place in many markets!

Product Recommendations made easy with Apache Druid Part 1

I have been playing with Apache Druid for a bit now and I have to say I am very impressed with this package. Druid provides fast analytical queries, at high concurrency, on event-driven data. Druid can instantaneously ingest streaming data and provide sub-second queries to power interactive UIs.-link. Apache Druid essentially does all of the bulk lifting of segmenting the data and putting it into high performing indexes for super fast queries . You can stream the data directly into Druid using API’s or Apache Kafka, or you can simply upload massive amounts of data at intervals appending or replacing.

Because Druid does so much for you, you could actually run different campaigns using completely different data sources that are stored and indexed in Druid. Imagine running a campaign for “Hottest Items Last Fall” or “Seasons top sellers”. This would produce a product shelf similar to this on your eCommerce site:

Screen Shot 2019-08-07 at 10.17.20 AM.png

Those products could have been returned by Druid in real time, sorting the resulting SKU’s by order value, quantity sold and even filtered for things like shopper attributes (age, gender, location).

Screen Shot 2019-08-07 at 1.40.12 PM.png

Druid let’s you store as many data sources as you want, so you could actually build dynamic components in CoreMedia that can run the same campaigns on different data sources. This could be used for different brands and their SKU’s or even seasonal order data.

Screen Shot 2019-08-07 at 10.20.22 AM

For my use case, this means you could essentially push order line item data into Druid and get fast queries for product shelves like “Top Sellers“, “Top Weekend Sales“, or even “This weeks hits” – all based on the order line sales and the time and date stamp of the order.

Pushing this line item level order information should be trivial for most order management systems. I started to ask myself what data would I actually need to satisfy a few use cases. So I started writing some use cases down as one liners:

  • Most products sold
  • Total sales
  • Highest Total count sold on day of week
  • Highest Total count sold in month of year
  • Highest Total sales on day of week
  • Highest Total sales in week of year
  • Region top seller
  • Men top seller
  • Women top seller in region

——————————————————————————————

When should I use Apache Druid?

Read about how Neilsen, Monetate, eBay, AirBnB, and others use Apache Druid.
——————————————————————————————–

I then had to figure out the minimum amount of data needed to be able to do those use cases and this is what I came up with:

“time”, “order_id”,”shopper_id”,”sku”,”price”,”quantity”,”cost”, “shipping_info”

That is all pretty standard information you can get from a PO. What is not part of that is the customer demographic information.  Because Druid performs best with flat data we will most likely have to write a routine that combines order line data with customer attribute data. We could include fields like these (if they are known):

“age”, “region”,“gender”:

This would allow us to ask Druid many different queries and get the proper response. In the CoreMedia extension model this should really be a returned list of SKU’s that we can map to the current product catalog. Some error handling or SKU replacement code might be needed; especially if you are running against year old data. Hopefully for more current campaigns like “Hottest Weekend Products” or “What’s hot this month” the data and SKUs very up to date. The resulting JSON sent in for each row would look like this:

{
"time":"2019-06-30 03:53:35",
"order_id":"id_055300006130",
"age":"40",
"region":"Midwest",
"gender":"M",
"shopper_id":"U_09080785",
"sku":"PC_CHEF_CORP_MP_KNIFE_SIGNAL_RED_SKU",
"price":79.0,
"quantity":3,
"cost":237.0
}

Sending in each order line item separately will allow Druid to actually dynamically build orders, return SKU’s based on any time and date combination, bloom filters, numeric expression, and of course grouping (total sales for a single SKU)- link.

I created a dataset with six months of order data, broken out by each line item as described above. It ended up being 431,148 line items created for 4,323 SKU’s in 300,000 orders

I went ahead and created queries for each of those use cases and I find Druid is extremely fast (more on that in Part 2), even when running on my local machine. Check out the slide show below for the various ways you can use SQL (or JSON) to query Druid. The real power comes with the way Druid can quickly return rows and run on functions like TIME_EXTRACT. Each query essentially returns a list of SKU’s ordered descending from either a total sales count or an items sold count.

This slideshow requires JavaScript.

Stay tuned for part 2 where I show how easy these kinds of dynamic product shelves based on sales and shopper data can be integrated into CoreMedia Studio. I will also show a demonstration where Apache Druid is accessed in realtime from our Studio where the maketing person can easily preview this dynamic behavior. A little teaser showing how the authoring environment (Preview CAE) and the runtime environment could access the same Druid data, giving marketers the same products as the shoppers would see.

 

I am really interested in hearing your thoughts on this, send me an email or leave a comment!

Screen Shot 2019-08-07 at 3.45.25 PM.png

CoreMedia Demo Jam 3 – Time travel is possible!

Scheduling content and delivering campaigns can be difficult, especially if it requires multiple teams to deliver the content or even worse, the dreaded IT involvement. Personalized content based on shopping behavior, demographics, or simply by date and time can be difficult if you can’t preview the site hitting the various rules. This is where CoreMedia Studio enables you to see your site as different personas or even at a different date and time with ease . Some people say time travel is impossible, Ancient CoreMedia Architects say otherwise…

In this Demo Jam I show how easy it is to set up rules for content to show on specific days, just one of the ways you can run your campaigns and keep your site fresh each day.

If you didn’t get the reference to Ancient Aliens, make sure you watch it on the History Channel Friday evenings.

Integrating the Tweet Text CKEditor Plugin into CoreMedia Studio

This post was inspired by the Tweetable Text CK Editor plugin by ardnet. One of my awesome colleagues, Drew Bowers, took the idea and extended the CoreMedia Studio with a similar plugin. This plugging allows readers to click on a line of text, which then launches Twitter and prepares a Tweet with the quoted text and a link back to the original article. The extension is fairly straightforward and mostly in CSS and JavaScript.

Let your readers Tweet your content easily with this plugin!

Here is a quick tutorial in getting the Tweet Text plugin up and running into your CoreMedia Studio environment as well as in the runtime (the Content Application Engine or otherwise known as the CAE):

Presumptions: Knowledge on how to add a new generic extension to studio & studio development

Setup

1. Download and Extract the Tweetable Text plugin to a temporary directory

2. Create a new Maven module within the workspace/modules/extensions directory (i.e “twitter”)

3. Inside new maven module create a new maven module with the Flash template (name: “twitter-ckeditor“)

4. Inside the flash plugin module “twitter-ckeditor

  • create src/main/joo (if not already created)
  • create package for the studio plugin mxml files (inside of src/main/joo):
    • com/coremedia/blueprint/twitterckeditor/studio
  • create sencha folder (inside of src/main/joo)
  • inside sencha folder:
    • create package “resources/ckeditor/plugins/ twitterckeditor “
    • create package “joo/resources

Example setup:

Note: this folder is built inside of the extensions directory of your CM Workspace

5. Adding the plugin files (css/js/etc)

  • inside the joo/resources folder
    • create “css”, “js”, and “images” folder
      • add the css, js, and any images from the plugin into these folders
    • inside the ckeditor/plugins/my-plugin folder
      • move plugins.js to this folder from the temporary directory (this is the main js of the plugin)

Example setup:

Updating the pom.xml to include the resource files

  • inside the “my-plugin-ckeditor” pom.xml:
    • inside of build tags
      • create a resource path to the sencha folder
      • create a plugins tag and add the css, js, and other paths as seen below
      • Make sure the additionalCssNonBundle file paths match the folder structure of the project

Example setup:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.coremedia.blueprint</groupId>
    <artifactId>twitter</artifactId>
    <version>1-SNAPSHOT</version>
  </parent>

  <artifactId>twitter-ckeditor</artifactId>
  <packaging>swc</packaging>

  <properties>
    <coremedia.project.extension.for>studio</coremedia.project.extension.for>
  </properties>

  <dependencies>
    <dependency>
      <groupId>com.coremedia.ui.toolkit</groupId>
      <artifactId>ui-components</artifactId>
      <type>swc</type>
    </dependency>
    <dependency>
      <groupId>com.coremedia.ui.sdk</groupId>
      <artifactId>editor-components</artifactId>
      <type>swc</type>
    </dependency>
    <dependency>
      <groupId>net.jangaroo</groupId>
      <artifactId>ext-as</artifactId>
      <type>swc</type>
    </dependency>
    <dependency>
      <groupId>net.jangaroo</groupId>
      <artifactId>jangaroo-runtime</artifactId>
      <type>swc</type>
    </dependency>
  </dependencies>


  <build>
    <resources>
      <resource>
        <directory>src/main/sencha</directory>
        <targetPath>../packages/${project.groupId}__${project.artifactId}</targetPath>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>net.jangaroo</groupId>
        <artifactId>jangaroo-maven-plugin</artifactId>
        <version>${jangaroo.version}</version>
        <extensions>true</extensions>
        <configuration>
          <namespaces>
            <namespace>
              <uri>exml:com.coremedia.blueprint.twitterckeditor.config</uri>
            </namespace>
          </namespaces>
          <globalResourcesMap>
            <ckeditor.plugin.tweetabletext>
              ckeditor/plugins/tweetabletext/plugin.js
            </ckeditor.plugin.tweetabletext>
          </globalResourcesMap>
          <additionalCssNonBundle>
            <value>resources/joo/resources/css/tweetabletext.css</value>
            <value>resources/joo/resources/images/tweetabletext.png</value>
          </additionalCssNonBundle>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Development

In this step, the studio-plugins are created that load the ckeditor content

For this a driver plugin is needed that loads the menu code & ckeditor plugin

Note: The naming convention is important! Make sure that the <fx:Script> sections of each .mxml file have the proper variable & function name set (it should just be the name of the plugin without extension). CM Studio relies on these definitions to build the connection between the runtime and plugins.

1. In the package com/coremedia/blueprint/twitterckeditor /studio:

  • Create TwitterCkEditorPlugin.mxml

Use this code for that file:

<?xml version="1.0" encoding="UTF-8"?>
<ui:NestedRulesPlugin
        xmlns:exml="http://www.jangaroo.net/exml/0.8"
        xmlns="exml:ext.config"
        xmlns:ui="exml:com.coremedia.ui.config"
        xmlns:fx="http://ns.adobe.com/mxml/2009">
    <fx:Script><![CDATA[
    private var config:TwitterCkEditorPlugin;

    public native function TwitterCkEditorPlugin(config:TwitterCkEditorPlugin = null);
    ]]></fx:Script>


  <ui:rules>
    <ui:RichTextArea>
      <ui:plugins>
        <ui:AddCKEditorPluginsPlugin plugins="tweetabletext" />
        <ui:CustomizeCKEditorPlugin>
          <ui:ckConfig>
          </ui:ckConfig>
        </ui:CustomizeCKEditorPlugin>
      </ui:plugins>
    </ui:RichTextArea>
  </ui:rules>
</ui:NestedRulesPlugin>

  • Create TwitterCkEditorMenuPlugin.mxml

  • add the following toolbar code

  • Create MyPluginCkEditorStudioPlugin.mxml

<?xml version="1.0"?>
<ui:NestedRulesPlugin
        xmlns:exml="http://www.jangaroo.net/exml/0.8"
        xmlns="exml:ext.config"
        xmlns:ui="exml:com.coremedia.ui.config"
        xmlns:editor="exml:com.coremedia.cms.editor.sdk.config"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:local="com.coremedia.blueprint.twitterckeditor.studio.*">

  <fx:Script><![CDATA[
    import com.coremedia.cms.editor.sdk.premular.fields.RichTextPropertyField;
    import com.coremedia.ui.ckeditor.RichTextAction;

    private var config:TwitterCkEditorMenuPlugin;

    public native function TwitterCkEditorMenuPlugin(config:TwitterCkEditorMenuPlugin = null);
    ]]></fx:Script>

  <ui:rules>
    <Toolbar>
      <plugins exml:mode="append">
        <ui:AddItemsPlugin>
          <ui:items>
            <ui:IconButton itemId="twitter-icon"
                           iconCls="twitter-ck-icon"
                           tooltip="Twitter Markup"
                           text="Twitter CK">
              <ui:baseAction>
                <ui:RichTextAction commandName="tweetabletext" />
              </ui:baseAction>
            </ui:IconButton>
          </ui:items>
          <ui:after>
          </ui:after>
        </ui:AddItemsPlugin>
      </plugins>
    </Toolbar>
  </ui:rules>

</ui:NestedRulesPlugin>

  • add TwitterCkEditorPlugin.mxml & TwitterCkEditorMenuPlugin.mxml

<?xml version="1.0"?>

<editor:StudioPlugin
  xmlns:fx="http://ns.adobe.com/mxml/2009"
  xmlns:local="com.coremedia.blueprint.twitterckeditor.studio.*"
  xmlns:exml="http://www.jangaroo.net/exml/0.8"
  xmlns="exml:ext.config"
  xmlns:ui="exml:com.coremedia.ui.config"
  xmlns:editor="exml:com.coremedia.cms.editor.sdk.config"
  xmlns:u="exml:untyped">
<fx:Metadata>

</fx:Metadata>
  <fx:Script><![CDATA[
    public static const xtype:String = "com.coremedia.blueprint.twitterckeditor.studio.config.twitterCkEditorStudioPlugin";

    private var config:TwitterCkEditorStudioPlugin;

    public native function TwitterCkEditorStudioPlugin(config:TwitterCkEditorStudioPlugin = null);
    ]]></fx:Script>

  <editor:rules>

    <editor:RichTextPropertyField>
      <editor:plugins>
        <local:TwitterCkEditorPlugin/>
        <local:TwitterCkEditorMenuPlugin />
      </editor:plugins>
    </editor:RichTextPropertyField>

  </editor:rules>
</editor:StudioPlugin>

  • Create manifest.xml

<?xml version="1.0"?>
<componentPackage>
  <component class="com.coremedia.blueprint.twitterckeditor.studio.TwitterCkEditorMenuPlugin"/>
  <component class="com.coremedia.blueprint.twitterckeditor.studio.TwitterCkEditorPlugin"/>
</componentPackage>

These 3 plugin files & the manifest tell the Studio runtime that a new plugin has been added to the RichTextArea (aka the CK Editor) and that it is to utilize the toolbar code plugin (MyPluginCkEditorMenuPlugin.mxml)

2. Now build the Studio Webapp via maven: mvn clean install -pl :studio-webapp -am -DskipTests

  • This step could take 7-10mins depending on the hardware

3. Run studio if the build was successful: mvn tomcat7:run inside of modules/studio/studio-webapp

Note: optionally provide the -Dinstallation.host=<url of local/remote host> to run studio against another environment. Local studio version and remote studio version need to be the same version (i.e 1901, 1904, etc)

4. Check if plugin was loaded (in this case the Twitter Icon shows on the richtext toolbar for CMArticles)

5. Once the plugin is loaded, all that’s left is to make sure that the actual javascript logic functions properly inside the studio plugin (this can be troubleshot quickly through browser tools).

Specific Customizations for Tweetable Text

As part of the integration work done for this specific plugin, the default logic of the plugin needed to be revised to better work within the CoreMedia studio. All this frontend work was done utilizing the CoreMedia frontend workflow, that easily lets developers create & modify their themes/frontend logic without having to rebuild the entire Content Application Engine. This workflow utilizes yarn to automatically push updated webpacks to the CoreMedia host server whenever changes are made to the files!

CKEDITOR.plugins.add('tweetabletext', {
  icons: 'tweetabletext',
  beforeInit: function () {

  },

  init: function(editor) {
    //editor.addCommand('tweetabletext', new CKEDITOR.dialogCommand('tweetabletextDialog'));
    editor.addCommand('tweetabletext', new CKEDITOR.command(editor, {
      exec: function(editor) {

        var selection            = editor.getSelection();
        var range                = selection.getRanges()[ 0 ];
        var html = "";
        var className = range.startContainer.$.className;
        if (className !== "tweetabletext") {
          // if text isnt already 'tweetable', mark it as tweetable and insert new HTML
          var textToWrap     = selection.getSelectedText();
          html  = '<a class="tweetabletext" _xlink:href="#">';
          html += textToWrap + '</a>';

          //html    += '<img src="' + iconPath + ' alt="twitter icon" >';
        } else {
          // set new html to be the inside text of selection with tweetable status
          html = getSelectionHtml();
        }

        // clean old tweetabletext instances
        $(".tweetabletext").each(function() {
          var value = $(this).text();
          if(value == null || value.length === 0 || value === ' ' || value === " ") {
            $(this).remove();
          }
        });

        // insert new selection
        editor.insertHtml(html);
      }
    }));

    //editor.addCommand('untweetabletext', new CKEDITOR.unlinkCommand());

    editor.ui.addButton('TweetableText', {
      label: 'Insert TweetableText',
      command: 'tweetabletext',
      toolbar: 'insert'
    });

    if (typeof editor.config.contentsCss === 'object') {
      editor.config.contentsCss.push(CKEDITOR.getUrl(this.path + 'css/tweetabletext.css'));
    }
  }
});

function getSelectionHtml() {
  var html = "";
  if (typeof window.getSelection != "undefined") {
    var sel = window.getSelection();
    if (sel.rangeCount) {
      var container = document.createElement("div");
      for (var i = 0, len = sel.rangeCount; i < len; ++i) {
        container.appendChild(sel.getRangeAt(i).cloneContents());
      }
      html = container.innerHTML;
    }
  } else if (typeof document.selection != "undefined") {
    if (document.selection.type == "Text") {
      html = document.selection.createRange().htmlText;
    }
  }
  return html;
}

For this exercise we have streamlined the main plugin.js file to contain all logic necessary to mark the text as tweetable

The code below is the js code that is invoked when the studio-user selects the twitter button

We also added appropriate front end logic (the end user site) to facilitate the opening of the Twitter link

First was to create a new ‘brick’ within the frontend workspace. In CoreMedia, bricks serve as generic frontend logic packages, usually a specific brick for each layout in the system. These bricks are typically available across all sites and e-commerce systems regardless of the theme used, so this is the best place to put this logic.

The project files to the right are located within:

<workspace>/modules/frontend/lib/bricks

The twitter-richtext.js contains all the on-click logic for the tweetable text:

//import * as logger from "@coremedia/js-logger";
import $ from "jquery";
/**
 * Displays a simple text in the console.
 *
 * @function consolePrint
 * @param {String} $text - The text to be displayed in the console.
 */
export function consolePrint($text) {
//  logger.log($text);
}

$(function() {
// abowers - added to support frontend useage of twitter extension
  $(".tweetabletext").on("click", function (e) {

    let twitterBaseUrl = 'http://twitter.com/intent/tweet?text=';
    let text = e.target.innerText + "\n\n" + window.location.href;
    text = encodeURI(text);
    twitterBaseUrl += text;
    let win = window.open(twitterBaseUrl, '_blank');
    if (win) {
      //Browser has allowed it to be opened
      win.focus();
    } else {
      //Browser has blocked it
      alert('Please allow popups for this website');
    }
  });
});

The CSS utilizes the standard CoreMedia frontend development framework of SCSS to build out the needed CSS logic in a modular format.  All the CSS for the frontend for this module is in _tweetable-text.scss. The _partials.scss file imports the tweetable text scss, and they are compiled by the yarn workflow into regular CSS.

_tweetable-text.scss:

.tweetabletext {
  background: none repeat scroll 0% 0% #FFFFFF;
  color: #555;
  text-decoration: none;
  font-weight: normal;
  border: none;
}

.tweetabletext::after {
  padding-left: 5px;

  content:url("../../img/tweetabletext.png");
}

.tweetabletext:hover {
  background-color: #E2F1F9;
}

_partials.scss: (add this line)

@import "partials/tweetable-text";

The next step is to compile the new brick with the following commands, ran inside of the brick’s folder

  1. yarn –production run
  2. yarn install

The last steps are to update the site theme to utilize the new brick code. This is done inside of the package.json inside of the theme folder. Add the line in bold to your theme dependencies block in the json:

"dependencies": {
...
"@coremedia/brick-twitter-richtext": "^1.0.0",
...
}

Finally, inside of the theme folder run the following commands to recompile & build the theme with the new brick.

  1. yarn –production run
  2. yarn install
  3. yarn start (to test theme in developer mode)

From here, if the brick and theme were updated correctly, add the final theme to the deployed CoreMedia studio, and the work is done.

In case you missed the Demo Jam video I put together, you can see this extension in action in under 3 minutes:

DemoJam: CoreMedia Studio Extensions!

In this quick three minute tutorial I show a CoreMedia Studio extension my team put together based on a CK Editor plugin that enables editors to tag lines of text in articles to be “tweetable” by the reader. A sample would be: this gives your readers an easy way to tweet quotes from your articles!

Stay tuned here for a tutorial for this extension with source code and be sure to subscribe to my new YouTube Channel: CoreMedia Demo Jams!