The CommonSpot Widget architecture was developed to maximize widget functionality and flexibility as well as minimize duplication of “common” elements that are shared by most of the Widgets.
The CommonSpot Widgets are typically made up of the following components:
Widget Properties which are defined in one or more Metadata Forms bound to the Widget’s Render Handler and exposed in the UI through the ‘Custom’ menu on the element menu.
Data. The content and/or content specific options set in Standard or Custom Elements.
Render Handlers. They combine the Properties and Data to build the HTML structure for the Widget.
Common Widget Custom Elements. For common data such as colors, text sizes, button styles, and button sizes.
Widget Properties (Metadata Forms)
Configurable options entered via CommonSpot Custom Metadata Forms which are bound to the Widget’s Render Handler(s) to set specific global properties for the entire instance of the Widget.
The Metadata Form(s) for each Widget, define the Widget specific option for that Widget. They use a variety of field types to collect the necessary data, however a couple new Field Types were developed specifically as part of developing the first set of Widgets (and are available in version 2.3 of the ADF) that may be useful to you. Those include:
Field Settings - Allows for the collection of several common types of properties ( Tag, Alignment, Size, Font Settings, Color, Background Color, Border Color, Style, Effects and Padding/Margin)
Device Size Options - Allows for the collection of settings based on device sizes (Small Phone, Phone, Tablet, Desktop, Large Desktop)
Widget Data (Custom/Standard Elements)
Content entered via CommonSpot Standard and Custom Elements for specific item records of widget for display as well as per item options.
All of the widgets that PaperThin provides ship with a Custom Element (or use one of the Standard Elements), however for some widgets you are able to use your own Custom Elements instead.
Some of the standard CommonSpot elements to which Widgets are bound include:
- Containers (Read More Widget and ScrollSpy Widget)
- Formatted Text Blocks (Read More Widget)
- Link Bars (Horizontal & Vertical Tab Widgets)
- Tab Bars (Horizontal & Vertical Tab Widgets)
- Page Index (Read More and Video Textblock Widget)
- Tree Navigation (Slider Menu)
Widget Render Handlers
Where appropriate, render handlers provided with the Widgets are ‘Generic’ Render Handlers, meaning that they can be bound to your own Custom Elements or to certain Standard Elements. This means that you can use the Widgets across different content types. For example, you could use the Image Textblock Carousel widget to display News Stories, Blog Posts, Profiles, Testimonials, etc. Any element that has a Title, Subtitle, Image and Link can be bound to the widget.
Widget Render Handlers are also built using the power of ColdFusion Components to share common code among widgets. This widget Component hierarchy also allows for overriding of specific methods to handle customization of rendering and data. See the “Widget Component Hierarchy Structure” section to understand more about the components architecture that makes up the very powerful widget render handlers.
Widget Render Handlers include:
Generic Render Handlers
Field Mappings - Allowing you to use your own Custom Element fields mapped to the widgets configured fields.
Standard Render Handlers
Used with some CommonSpot Standard Elements
Rendering Component Objects (CFML cfc)
Extending the shared Common Component (via CFML cfc extends attribute)
// Create the Image Textblock Component csWidget = CreateObject('component','_cs_widgets.csw-imagetextblock.renderhandlers.csw-imagetextblock-common'); // load necessary resources csWidget.loadResources(); // exit if all we're doing is detecting required resources if( Request.RenderState.RenderMode EQ "getResources" ) exit; if( NOT structKeyExists(attributes,'elementinfo') ) exit; // Load the Properties from the metadata form props = csWidget.loadProperties(Attributes.ElementInfo,Variables.Caller); // Make sure we have Props data if( NOT csWidget.hasProperties(props) ) exit; // Get the element Data and Render the items if( StructKeyExists(Attributes.ElementInfo.ElementData, 'PropertyValues') ) csWidget.getAndRenderItems( Attributes.ElementInfo.ElementData, props );
In the Widget’s main render handler .cfm file there is a call to the method loadResources(), which is impelemented in the Widget's main CFC. This call adds the required resources and any custom override resources to the CommonSpot Resource management queue. Resources loaded can be:
- Gobal resources (like jQuery)
- Common Widget resources (such as for text, buttons, etc.)
- Third party resources (such as jQuery plugins, etc)
- Located in subdirectories under the '/_cs_widgets/_resources/' directory, or within the /ADF/ directory
- Widget specific resources (widget specific css & js)
- Located within the specific widgets directory
Within the Widget's CFC loadResources() method you will see code like this:
Additional override hooks have been added to each Widget to allow custom overrides to be configured and loaded. Using these hooks helps preserve the code that comes bundled with the widget.
if( StructKeyExists(Request.Site.CS_Resources.Resources_by_name, 'cswImageTextblock_custom') ) Server.CommonSpot.udf.resources.loadResources("cswImageTextblock_custom");
To enable an override hook, create a resource that shares the same name with the resource to be overridden and append a “_custom” suffix to the name and/or the alias. Make sure the “_custom” resource is sorted to load after the widget resource. When the widget loads it will find and load the custom resource.
Common Widget Custom Elements
Most of the Widget’s provided by PaperThin utilize a common set of attributes to control widget rendering. These include Colors, Text Sizes, Button Sizes and Button Styles.
As part of importing a Widget that utilizes these common properties, the Widget will create and populate the following Global Custom Elements:
If you want, you can add to, or remove items in these Custom Elements, controlling the Colors, Sizes and Styles presented to your contributors.
Widget Component Hierarchy
Each widget contains the following file types:
A standard or ‘generic’ render handler located in the widget’s ‘/renderhandlers/’’ directory. For example, the Image Textblock Widget's path is /_cs_widgets/csw-imagetextblock/renderhandlers/csw-imagetextblock-generic.cfm
One or more CFC component files, located in the widget’s /renderhandlers/ directory, which contain commonly named methods that implement the widget’s functionality. Such common methods include:
For example, for the Image Textblock Widget there is a CFC file named /_cs_widgets/csw-imagetextblock/renderhandlers/csw-imagetextblock.cfc
The standard or generic render handler will instantiate an instance of this CFC and call its methods.
The widget specific component will typically derive from a common base component in the /_cs_widgets/_common/ directory named csw-common.cfc, which implements common methods. See the ‘Common Rendering’ section below for details.
One or more CSS files in the widget’s /CSS/ directory.
For example, for the Image Textblock Widget there is one CSS file in the /_cs_widgets/csw-imagetextblock/css/ directory named csw-imagetextblock.css
The CSS files are loaded using CommonSpot’s resource loading framework.
JS Files and/or jQuery Plugins
One or more JS files in the widget’s /CSS/ directory, plus any jQuery plugin under the /_csw_widgets/_resources/ directory that are needed by the widget..
For example, for the Image Textblock Widget there is one JS file in the /_cs_widgets/csw-imagetextblock/js/ directory named csw-imagetextblock.js
The JS files are loaded using CommonSpot’s resource loading framework.
For example, the Image Textblock Widget utilizes the files under the /_cs_widgets/ directory:
Render Handler file registered in CommonSpot:
CS Widgets are built to be extremely configurable through both the UI and at the code level.
Customizing via UI:
There are two means for customizing Widgets from the CommonSpot UI:
- Add, Update or Delete pre-defined data in the Common Widget Custom Elements
- Choose the ‘View Data...’ menu option on any of the pre-populated Widget Custom Elements, then add, update or delete the existing data. Note this will update the options for Color, Size and Style for all Widgets that reference this data.
- Override any Field in either the Widget’s Custom Element or Metadata Forms.
- Using the new capability in CommonSpot 10.5, you can now override the definition of any field in a locked Custom Element or Metadata Form by clicking the icon in the Overrides column. This allows the element to be reimported later, should there be changes or improvements.
Customizing via Code:
With an understanding of common shared widget components and resources, as well as any widget specific components and resources, a developer will be able to successfully adapt the out-of-the-box widget to the specific need of the site build or enhancement.
To customize the code we recommend that you do the following:
- Create a copy of the Widget Render Handler CFM file you want to customize.
- Register it with the Custom Element or the Standard Element where the data will be housed.
- Bind it to the new Render Handler of the appropriate Widget Metadata form.
- Create a new blank custom widget CFC file. In the new custom widget CFC update the extends path to point to the copied Widgets CFC file.
- In the the new Render Handler, update the CreateObject path to point to your new custom Widget CFC.
- Any function found in the the copied widgets CFC file or up the derivation tree to the csw-common CFC file can now be overridden using CMFL native component inheritance to fit your specific need.
Since most Widgets share similar characteristics, such as Titles, Descriptions, Images and Links (or Buttons), they use a shared set of:
Common Rendering Methods
The common render methods are implemented in the CFC file:
Most of the Widget CFCs derived from this component, and their methods can be accessed directly.
Most methods take a ‘props’ and ‘data’ structure, where the ‘props’ structure is an associative array of the fields in the Widget’s Metadata Forms and the ‘data’ structure is an associative array of the “generic’ Render Handler fields or the element fields.
Below is an example of code to render a specific layout of the Image Textblock element:
<cfoutput> <div class="cswCard"> <div class="cswImageTextblockContainer"> <div class="cswOverlayWrapper"> #renderImage(data, props)# <div class="cswTextblock"> #renderOther(data, props)# #renderTitle(data, props)# #renderSubtitle(data, props)# #renderSeparatorLine(data, props)# #renderDescription(data, props)# </div> #renderButton(data, props)# </div> </div> </div> </cfoutput>
The following lists some of the common methods that are implemented in the /csw-common.cfc. Please review the file directly for specifics on the arguments taken and return values.
Properties and Data Processing
Common Widget CSS
Since many of the Widgets utilize similar components such as Cards, Buttons, Title, Subtitle, Images, Shadows, Column Layouts etc., the styles for these components are implemented in the following stylesheets and dynamically loaded as needed by the Widget.
Widget Style Sheets:
- Common Styles - csw-common-styles.css
- Card Styles - csw-card-styles.css
- Text Styles - csw-text-styles.css
- Image Styles - csw-image-styles.css
- Button Styles - csw-button-styles.css
Additionally, the Widget may load any third party resources that it needs, to provide specific rendering. These resources are housed under the /_cs_widgets/_resources/ directory in their own subdirectory, are already included in the ADF or are assumed to be loaded by your site already.