Structured Content in a Free-Form World

Originally posted on WSOL.com

Free-form content is so…free

It allows for the easy flow of ideas, and communication flies freely on the wings of the perfect word.

When I started working on the web, oh so many years ago, the idea of structured content didn’t exist. We all just wrote HTML. Everything went into a p tag, or—and I can’t belive we did this—a table (we were so young and naive back then).

Then I started working with a CMS. I would like to say that velvet ropes began to part and champagne fell from the sky, but the truth is, that free-form philosophy was still deeply ingrained. All the CMS did was give me a decent web interface in which to enter my HTML. And everything was fine, as long as I was the one in charge of entering and maintaining all of that content. Unfortunately, things went downhill quickly when other people started to get involved. We had headlines in pink, images with rainbow-colored callouts, pages with everything they could think of on them, and others with nothing—it was chaos.

That’s when I realized free-form content isn’t free. It has a cost.

It costs you control—unless you are the one doing everything, and who has time for that?

It costs you consistency—unless everyone is diligent, concientious, and actually pays attention to the style guides, and who is excited to do that?

It costs you time—and there’s never enough of that.

Structured content is so…restricted

It forces all of your nifty ideas into little boxes and fields, putting your perfect words behind bars.

Once I realized that free-form content wasn’t so great, I started taking a look at structured content. For Ektron, that meant smart forms. I may have gone a little bit overboard for a while. I put everthing into smart forms. A list of items? No problem, here is a smart form with a repeatable group box to build that for you. You want a hyperlink? We can do that. Here’s a form with three fields for you to fill out in order to get that link on the page.

It worked, kind of. The pink headlines went away, and the only rainbows on the site were in pictures of the sky after a rainstorm. But there was still no champagne falling from the sky, and not one velvet rope parted for me.

I realized that I had gone too far toward the other extreme, and it had a cost.

It cost us the freedom to be creative—and everyone wants that.

It cost us the ability to be flexible—and everyone needs that.

It cost a lot of trust—because each project is unique, and I couldn’t deliver.

Back away from the extremes and proceed smoothly down the middle

When I started working for WSOL, I found that they already had some great solutions for doing exaclty what I now know we should have been doing all along: find a middle ground between free-form and structured content. Smart forms to direct the users down the paths they need to go for consistency on the website, while still allowing for free-form content that plays well within that structure.

Would you like to have a tabbed interface? No problem! We have just the smart form to do that. How about multiple columns, which can include other content blocks? We have that covered too.

The great thing is that these experiences are not a complete failure if you learn something. My journey taught me that going to the extremes is rarely a good thing, and that what we need is a happy median, some middle ground, where we have the structure for consistency, but are still able to be creative.

Do you want to be able to edit your website with the confidence that you can add whatever content you want while still maintaining a stylistic consistency? Contact us to learn more about how we can help you find this happy medium, or feel free to leave a comment below and share any questions or comments you might have about structured vs. free-form content.

Old Tricks – XSLT files and Smart Forms

It’s funny how you can work with a product for years, and then finally learn about
something that turns into a complete game changer. Take smart forms for example.
Smart forms provide a way to have structured content stored in the CMS.

Structure always sounds good, but why would you want to have structured content
instead of unstructured html content? I think Bill Cava (@billcava) explained
it best in his Ektron Content Types webinar
(http://www.ektron.com/Resources/Webinars/Ektron-Content-Types/)

Read the full post on my Ektron Community Blog

Thank You James and Ken

This huge thank you goes out to James Stout (tweetjaytem @egandalf) and Ken McAndrew (tweetjaytem  @kmac23va). Let me explain why.

Last November, Ektron hosted their annual customer conference, Synergy, in Washington D.C. These are great events that give the customers an opportunity to meet the people responsible for the CMS system that they use, partner companies who can help them realize their web site visions, and other Ektron clients.

When I worked for Canyon County, ID, I had the opportunity to attend the 2009 and 2010 conferences in Orlando, Florida, but when I started working for Ektron, I figured those would be my last ones. It’s expensive for a company to send people to a conference, even one that they are hosting, and sending a brand new developer didn’t make any sense.

After Ektron shut down their PSG group (see When Dreams Change),  I started working for WSOL, one of Ektron’s top partners. When Synergy 2012 was announced, I didn’t expect to go. This is a major marketing event for WSOL, and they send the people that can best represent the company, the Chief Operating Officer Bill Casey, the Director of Design and Development, Chris Osterhout, and the head of Sales, Brian Elrich.

When the keynote speakers were announced, I was very excited to see that Ethan Marcotte (tweetjaytem  @beep) and Luke Wroblowski (tweetjaytem @lukew) were going to be speaking. Ethan is the guy who started the whole “Responsive Web Design” trend, and Luke is the evangelist for designing for Mobile first, and then for the desktop. These are two of my internet heroes, and I really wanted to meet them. So, in traditional geek fashion, I expressed my desire, and regret that I wouldn’t be going, on Twitter. This generated some interesting conversations, and at one point I jokingly suggested that I should get a life size cardboard cut-out of me, and have it standing up at the conference. That got some laughs, and then was forgotten. Or so I thought.

In late October, as the Synergy excitement was really ramping up, James brought it up again. He was going to be one of the technical speakers at Synergy, and he hinted that if I got the cut-out to him, he might have it on stage during his presentation. I thought this would be hilarious, so I started shopping around.

It turns out that it is pretty easy to get a life-size cardboard cut-out made, but not cheap for a gag. But then I found a company that made what they called “head-ka-bobs”, where the y basically take a picture of someone’s head, and put it on a stick. Perfect, and it was reasonably priced. So the #FaceOfJoe was born. (We even started the #FaceOfJoe hashtag on Twitter. It never trended, but I still hold out hope.)

tumblr_md6oq1nhpE1rjftawo1_1280

I had the #FaceOfJoe shipped to Ken McAndrew at C-Span. Ken was also scheduled to speak at Synergy, as since it was in Washington D.C., Ken’s home base, it made sense.

Ken took the #FaceOfJoe to Synergy. Between he and James, they took many pictures with people holding the #FaceOfJoe, got it on stage with many of the speakers, and even got photos  Ethan Marcotte and Luke Wroblowski each holding it.

In addition, they started a Tumblr blog to document the #FaceOfJoe’s adventures throughout Synergy. http://joegoestosynergy.tumblr.com I can’t remember laughing so hard.

So, I wanted to say a big thank you to every one who participated, and for being willing to pose for a picture with a ridiculous card board cut-out of my head. Thank you to Ken and James for hauling the #FaceOfJoe around to all of those sessions. For taking all of the pictures; for approaching people to see if they were willing to have their picture taken; for being such good friends, and good people; and for making me feel like a part of the event, even though I wasn’t there in person. This was a Synergy that I will never forget.

A User Control by Any Other Name

I have a confession to make, when Ektron announced their PageBuilder functionality, with the drag & drop widgets, I wasn’t excited. I was happy building pages the way I had been, and historically, a good bit of my time was spent fixing pages that my content editors had messed up, because they didn’t listen to what I had told them. So why would I be interested in a technology that gave them more control?

Then I watched Jason Arden’s Lunch and Learn webinar, that talked about PageBuilder, and the widgets, and I finally saw the potential. (When I built my first widget, dragged it onto a page, and it actually worked, I think I may have even done a happy dance.)

Fast forward a few months, I had built a widget to handle a specific problem (I don’t remember what it was), and then found that I needed the same functionality, but I couldn’t use PageBuilder in that circumstance. Being the innocent and naive soul that I was back then, I didn’t know that widgets where just dressed up user controls. (Sure, they had the same extension, but what does that mean anyway?) So I copied the code into a standard user control, removed all of the widget specific portions, and had two version with the same functionality. Two versions where I had to make changes, when they were inevitably needed. Not ideal.

I have recently learned that you can use Widgets just like you would a normal user control. Since code re-use is a goal of all back-end developers, this was an exciting revelation for me, and it just takes a few simple changes to your widget code.

NOTE: I am not going to go into depth about how to build widgets, or all of the components of one. James Stout ( @eGandalf) has written some outstanding blog posts, walking you through widget development http://www.ektron.com/blog/egandalf/. )

The examples and screenshots for this post were all built on the 8.5 CMS platform, but you could easily do this on 8.0 as well.

 

Let’s jump in.

For this example, I will be using the HelloWorld widget. This widget is standard in the Ektron 8.0+ CMS installs, and is about as simple as widgets get, so it will be easy to explain the changes.

First, let’s take a look at the default HelloWorld widget code.

HelloWorld.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="HelloWorld.ascx.cs" Inherits="widgets_HelloWorld" %>
    <asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0">
        <asp:View ID="View" runat="server">
            <!-- You Need To Do ..............................  -->
            <asp:Label ID="OutputLabel" runat="server"></asp:Label>
            <!-- End To Do ..............................  -->
        </asp:View>
        <asp:View ID="Edit" runat="server">
            <div id="<%=ClientID%>_edit">
                 <!-- You Need To Do ..............................  -->
                 <asp:TextBox ID="HelloTextBox" runat="server" Style="width: 95%"> </asp:TextBox>
                  <!-- End To Do ..............................  -->
                 <asp:Button ID="CancelButton" runat="server" Text="Cancel" OnClick="CancelButton_Click" /> &nbsp;&nbsp;
                <asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" />
            </div>
        </asp:View>
    </asp:MultiView>

Not very complicated, and if you have looked at any of the widget code, this should be pretty familiar. We have the standard <%@ Control declaration statement at the top, and Asp Multiview control to show either the Normal view with an asp:Label for output, or the Edit view, with a simple form for updating and saving the widget properties.

 

In the code behind file, HelloWorld.ascx.cs

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Ektron.Cms.Widget;
using Ektron.Cms;
using Ektron.Cms.API;
using Ektron.Cms.Common;
using Ektron.Cms.PageBuilder;
using System.Configuration;

public partial class widgets_HelloWorld : System.Web.UI.UserControl, IWidget
{
    #region properties
    private string _HelloString;
   [WidgetDataMember("Hello World")]
    public string HelloString { get { return _HelloString; } set { _HelloString = value; } }
    #endregion

    IWidgetHost _host;
    protected void Page_Init(object sender, EventArgs e)
    {
        string sitepath = new CommonApi().SitePath;
        JS.RegisterJSInclude(this, JS.ManagedScript.EktronJS);
        JS.RegisterJSInclude(this, JS.ManagedScript.EktronModalJS);
        Css.RegisterCss(this, Css.ManagedStyleSheet.EktronModalCss);
        _host = Ektron.Cms.Widget.WidgetHost.GetHost(this);
        _host.Title = "Hello World Widget";
        _host.Edit += new EditDelegate(EditEvent);
        _host.Maximize += new MaximizeDelegate(delegate() { Visible = true; });
        _host.Minimize += new MinimizeDelegate(delegate() { Visible = false; });
        _host.Create += new CreateDelegate(delegate() { EditEvent(""); });
        PreRender += new EventHandler(delegate(object PreRenderSender, EventArgs Evt) { SetOutput(); });
        string myPath = string.Empty;
        if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ek_helpDomainPrefix"]))
        {
            string helpDomain = ConfigurationManager.AppSettings["ek_helpDomainPrefix"];
            if ((helpDomain.IndexOf("[ek_cmsversion]") > 1))
            {
                myPath = helpDomain.Replace("[ek_cmsversion]", new CommonApi().RequestInformationRef.Version);
            }
            else
            {
                myPath = ConfigurationManager.AppSettings["ek_helpDomainPrefix"];
            }
        }
        else
        {
            myPath = sitepath + "Workarea/help";
        }
        _host.HelpFile = myPath + "/Widget Chapter/Hello World/Creating the Hello World Widget.htm";
        ViewSet.SetActiveView(View);
    }

    void EditEvent(string settings)
    {
        HelloTextBox.Text = HelloString;
        ViewSet.SetActiveView(Edit);
    }

    protected void SaveButton_Click(object sender, EventArgs e)
    {
        HelloString = HelloTextBox.Text;
        _host.SaveWidgetDataMembers();
        ViewSet.SetActiveView(View);
    }

    protected void SetOutput()
    {
        OutputLabel.Text = HelloString;
    }

    protected void CancelButton_Click(object sender, EventArgs e)
    {
        ViewSet.SetActiveView(View);
    }
}

In this file, we see the normal using statements at the top; the widget property declarations, in this case just the one for HelloString (I did say this was a simple widget); the Page_Init function, that sets the widget properties, registers some javascript and css  files, and creates the delegates for the IWidget _host interface.

After that, is the EditEvent function, that populates the fields in the Edit view, which allows you to change the text that is going to be displayed on the screen. The SaveButton_Click function, which saves the values from the Edit form to the widget properties. The SetOutput function, which generally is used to build or populate the actual widget View output. And the CancelButton_Click function, which cancels the Edit mode.

In order to also use this widget as a standard user control, we need to make a few modifications.

I created a new user control file in the widgets directory: jaytemHelloWorld.ascx, and added the following code from the default widget.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="jaytemHelloWorld.ascx.cs" Inherits="widgets_jaytemHelloWorld" %>

<%-- Used to initialize a Script Manager is one does not exist --%>
<asp:PlaceHolder ID="phScriptManager" runat="server" />

<asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0">
     <asp:View ID="View" runat="server">
          <asp:Label ID="lblOutput" runat="server" />
     </asp:View>
     <asp:View ID="Edit" runat="server">
          <div id="<%=ClientID %>_edit">
               <asp:Label ID="lblHelloText" runat="server" AssociatedControlID="txtHelloTextBox" Text="Text to Display" />
              <asp:TextBox ID="txtHelloTextBox" runat="server" style="width: 95%" />
              <div>
                    <asp:Button ID="CancelButton" runat="server" Text="Cancel" OnClick="CancelButton_Click" />
                    <asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" />
              </div>
          </div>
     </asp:View>
</asp:MultiView>

 

The only real difference between the two is the addition of the Asp PlaceHolder control, just below the @Control definition. This will be used to add and initialize a Script Manager, if we are using this widget as a user control.

And the code behind: jaytemHelloWorld.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Ektron.Cms.Widget;
using Ektron.Cms;
using Ektron.Cms.API;
using Ektron.Cms.Common;
using Ektron.Cms.PageBuilder;

public partial class widgets_jaytemHelloWorld : System.Web.UI.UserControl, IWidget
{
	#region Properties

	private string _HelloString;

	[WidgetDataMember("Hello World")]
	public string HelloString
	{
		get { return _HelloString; }
		set { _HelloString = value; }
	}

	private IWidgetHost _host;

	#endregion

	#region Constructor

	public widgets_jaytemHelloWorld()
	{
		_host = null;
		HelloString = String.Empty;
	}

	#endregion

	#region Page Events

	protected void Page_Init(object sender, EventArgs e)
    {
		string sitepath = new CommonApi().SitePath;

		//Tries to populate host if PageHost exists
		_host = Ektron.Cms.Widget.WidgetHost.GetHost(this);

		//Keeps null reference from occuring when using as a standard user control
		if (_host != null)
		{
			_host.Title = "Jaytem's Hello World Widget";
			_host.Edit += new EditDelegate(EditEvent);
			_host.Maximize += new MaximizeDelegate(delegate() { Visible = true; });
			_host.Minimize += new MinimizeDelegate(delegate() { Visible = false; });
			_host.Create += new CreateDelegate(delegate() { EditEvent(""); });
			_host.ExpandOptions = Expandable.ExpandOnEdit;
		}

		ViewSet.SetActiveView(View);

		//If the Scriptmanager is null, then instantiate and add to placeholder control
		if (ScriptManager.GetCurrent(this.Page) == null)
		{
			ScriptManager sManager = new ScriptManager();
			sManager.ID = "sManager_" + DateTime.Now.Ticks;
			phScriptManager.Controls.AddAt(0, sManager);
		}
	}

	protected void Page_PreRender(object sender, EventArgs e)
	{
		if (ViewSet.GetActiveView() != View)
			return;

		//if HelloString is passed in the properties, use that
		if (!string.IsNullOrEmpty(HelloString))
		{
			lblOutput.Text = HelloString;
		}
	}

	#endregion

	#region Event Handlers

	protected void SaveButton_Click(object sender, EventArgs e)
	{
		HelloString = txtHelloTextBox.Text.Trim();
		_host.SaveWidgetDataMembers();
		ViewSet.SetActiveView(View);
	}

	protected void CancelButton_Click(object sender, EventArgs e)
	{
		ViewSet.SetActiveView(View);
	}

	#endregion

	#region Methods

	void EditEvent(string settings)
	{
		txtHelloTextBox.Text = HelloString;
		ViewSet.SetActiveView(Edit);
	}

	private void SetOutput()
	{
		lblOutput.Text = HelloString;
	}

	#endregion
}

The code is very similar, with a few important differences (Plus I like to organize my code a bit differently).

Just below the Properties region, I have a Constructor. The Constructor allows us to instantiate an instance of the widget user control, and set the properties without needing the PageBuilder functionality. The constructor also sets some default widget property values, which is very important.

I cleaned up the Page_Init function a bit, getting rid of some of the functionality that this widget really didn’t need (although it would be very useful in a more complex widget). I also added a check for the ScriptManager, checking to see if it is null or not (null means that this widget is being used outside of the PageBuilder environment). If the ScriptManager is null, then we need to create a new instance of it, and add it to the page. This is where the Asp:PlaceHolder control that we added to the .ascx page comes in.

After the Page_Init function, we have the Page_PreRender event function. The Page_PreRender event happens after the Page_Load, but before the page is rendered to the screen. When using widgets in the PageBuilder environment, the PreRender event handler is set using a delegate, and referencing the SetOutput function. In this case, we use the event when using this widget as a user control, we have to do it ourselves.

Everything else is exactly the same.

Let’s see it in Action

As a Widget

First, let’s start with using this widget as a widget. I have a very simple PageBuilder template, with a single drop-zone. My new widget is in the widgets directory, and I have added it to the Widgets list, and to the template in the WorkArea Settings.

I creates a new PB page, using my new template, and add the Hello World widgets by dragging and dropping the widgets into the drop-zone.

 

Next, I will edit the new widget, and update the text to be displayed.

I click save, and then Publish the PB page, so we end up with both widgets displaying on the page.

 

 

As a User Control

There are two ways that you can use your new widget as a user control: by adding a control to the .aspx page, and passing in the parameters as attributes; or by adding the user control to the page programmatically.

For this demonstration, I have very simple .aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="widget_uc.aspx.cs" Inherits="test_widget_uc" %>

<%-- Register the widget on the page, to use as a normal user control --%>
<%@ Register Src="~/widgets/jaytemHelloWorld.ascx" TagName="HelloWorld" TagPrefix="jtm" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
     <head runat="server">
          <title></title>
     </head>
     <body>
          <form id="form1" runat="server">
               <div>
                    <%-- Add the user control to the page --%>
                    <jtm:HelloWorld ID="jtmHW" runat="server" HelloString="Hello World. Broadcasting from the widget user control" />

                    <%-- Add an asp:PlaceHolder control, to add the widget user control to the page programmatically --%>
                    <p>
                         <asp:PlaceHolder ID="phControls" runat="server" />
                    </p>
               </div>
          </form>
     </body>
</html>

You first need to register the widget on the page. This needs to be done for both methods, or it won’t work.  Add a new <%@ Register  declaration, at the top of the page, but below the <% @ Page declaration. Put the path to the widget in the Src attribute, and give it a TagName and TagPrefix values.

Next, add the user control to the page in the markup, setting a new HelloString value. When you run the page, this is what you see:

 

Simple, right?

If you wanted to add the user control programmatically, it’s almost as simple. Here is the code behind file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class test_widget_uc : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
		ASP.widgets_jaytemhelloworld_ascx HelloWorld = new ASP.widgets_jaytemhelloworld_ascx();
		HelloWorld.HelloString = "So Long, and Thanks for all the Fish";
		phControls.Controls.Add(HelloWorld);
    }
}

In the Page_Load Event function, I am instantiating a new instance of the widget user control. Then I am setting the string that I want to output, and adding the control to an asp:PlaceHolder control that I have on the .aspx page. I like using PlaceHolder controls in this instance, because I can control the placement of the new user control on the page.

When you refresh the page, the second user control is added.

 

So there you have it. Having the option to use your widgets as standard user controls opens up some possibilities on your site, and is a great example of code reuse. You don’t have to create a new user control if you already have the functionality in a widget. Just use the widget.

Happy Coding.

What year is it anyway?

Over the last few years, Ektron has focused on a key theme each year, where most of their communications, presentations, and community outreach all focus on that theme. In 2010, it was the ‘Year of the Marketer’; 2011, the ‘Year of the Developer’, and now we are into 2012, and the new theme is clearly the ‘Year of the Designer.’

2010 Year of the Marketer

I was lucky enough to attend the Synergy conference in 2010. This was a great conference, with a focus on the Marketing and Business side of a website. I remember sitting in a session listening to Tom Wentworth ( @twentworth12) and Nicole Rogers ( @nicolekrogers), two dynamic and fun speakers, talk about how, if content is king, then context is queen.

We saw a big push on things like PageBuilder, which allows the non-technical folks to build complex pages on an Ektron site; the Analytics integration, which puts key demographic information of who is using what parts of your website into the hands of those who can make the most of it;  and showing us how Ektron could leverage a visitor’s context, from sources such as their recent browsing history, Facebook, or their physical location, to provide a unique, targeted experience.

Note: These are all very important things, but I am a developer at heart. While I find all of that interesting, not as important as how to build something cool.

2011 Year of the Developer

If you were an Ektron developer, then 2011 was your year!

We saw the release of version 8.5, which brought a slick new interface for the WorkArea; powerful new features and technologies such as the new FAST Search; and a completely redesigned Framework API, that makes building custom functionality to interact with the CMS so much easier.

In the Developer Community, there was the rise of the Ektron Exchange, that finally gave Ektron developers a place to share the widgets and code samples that they had developed over the years. The developer forums got a needed infusion of answers from knowledgeable Ektron folks, such as Andrew Eddy, James Stout, and Bill Cava, to name just a few. ( @andrew_eddy, @egandalf, and @billcava)

Developer Meetups were scheduled all over, where folks could get together and share their experiences and knowledge with other Ektron developers over dinner and drinks. If you were lucky enough to have a  Local User Group (LUGs) meeting somewhere close by, you go to see new examples of what was available today, and more importantly, what was coming in the future.

2012 Year of the Designer

We are now seeing the direction of 2012, which I am dubbing the ‘Year of the Designer’. In 2012, we are finally starting to see that a well designed website is so much more than something nice to look at, it also has to work for the user.

Part of this I am sure is driven by the enormous momentum that we all see with the mobile web, where having a well designed, functional site that works on any device (smartphone, tablet, desktop computer), could very well be the difference between a business’s success or failure.

Ektron has embraced the Mobile First philosophy, made famous by Luke Wroblowski ( @lukewMobile First), and they are busy promoting the relatively new, and fundamentally game-changing web design trend called Responsive Web Design, pioneered by Ethan Marcotte ( @beep, Responsive Web Design). The really great thing about 2012, is that Ektron is going to have both of these incredible individuals speaking at the annual Synergy conference this year. This one is not to be missed.

Note: These are two of my biggest web heroes. They are changing they way that we look at the web.

P.S.: Responsive Web Design is something that I have been interested in for some time. In 2011, I made a short presentation at the Seattle LUG, where I showed what might have been the first Ektron site using RWD (at least I like to think that it was), and that was followed up with a Developer interview with Bill Cava (Developer Webinar – Interview with Joe Mayberry), where I talked about Ethan Marcotte, and the potential that RWD has with the Ektron Platform.

An argument could be made that I had a hand in starting the momentum that led to the Year of the Designer. With that, a trip to D.C. in November, to see Luke and Ethan speak, would be the culmination of my efforts. What do you think? Maybe I should take up a collection.

When Dreams Change

It has been about a year since my life changed. In April of 2011, I saw a job posting on the Ektron web site for a Sales Engineer, and I thought I should go for it.

Now, at that point, I had been using the Ektron CMS platform for Canyon County, Idaho’s public and private websites for over three years, I was actively involved in the developer community, on both Twitter and the Ektron developer forums, and I was starting to be recognized. Because of my involvement in the developer community, I was asked to speak at Ektron’s Seattle Local Users Group meeting, and Bill Cava, Ektron’s Chief Evangelist, asked me to participate in a developer interview webinar (http://www.ektron.com/Resources/Webinars/Interview-With-Joe-Mayberry/)

The more I dealt with the folks at Ektron, the more impressed I was with the company, and the quality of people who worked there. I kept thinking that this would be a great place to work, so when I saw the Sales Engineer posting, I finally thought, “I can do that.” After all, I was already a client, and I could bring an informed perspective to the situation.

Before applying, I decided to reach out to friend I had made on Twitter, who had been in a very similar situation a couple of years earlier, and was now one of the most respected developers at Ektron. I asked for his opinion, and if life at Ektron was as good as I thought it would be. His answer surprised me. Not by what he did or didn’t say, but by the direction it went. He told me that the Sales Engineer job would be a great learning experience, but that he wasn’t sure if it was right for me, and that the group he was in had an opening.

It took a bit, a couple of telephone interviews, and what seemed like more emails than I can count, but they hired me. I was living the dream. I was doing work that I really enjoyed, working remotely, with some truly great people, and I learned. I learned how to push the Ektron CMS platform past anything I had ever thought of. And as we pushed it, I grew as well, and I was good at my job.

That’s when the dream changed.

Friday, March 30, 2012 started out just like any other. I went up to my office, a thermos of tea in hand, excited to build something cool. One of the first things I noticed was an email from Ektron’s CEO Bill Rogers, saying that there was a mandatory meeting in a couple of hours that I needed to call into. Being a remote worker, this wasn’t unheard of. A couple of my colleagues and I talked over instant message about it, wondering what was going on. We were curious, but not worried since we knew the company was doing really well.

When the meeting started, they got right to the point: Ektron was getting out of the services business, and we had lost our jobs, effective immediately. (You can read the official Ektron Corporate Update here: http://www.ektron.com/billrogersblog/Ektron-Corporate-Update/)

My dream had just become a nightmare.

Why did this happen? The company was doing really well, reporting a 35% rise in licensing over the last year, so why were they letting us go? More specifically, why were they letting me go? Hadn’t I been doing a good job?

A lot of people out there have probably disapproved and criticized Ektron and Bill Rogers for what they did, and how it was handled. I am not one of those people.

This wasn’t a personal decision. It was a business decision. Bill had decided to take the company in a new direction, which didn’t include us. He made the decision for what he believes to be for the betterment of his company, and only time will tell if he was right or not. Personally, I think he will be proved right.

I imagine that the decision to let so many of us go was a difficult one, at least I hope it was. Changing so many lives so suddenly should be a hard decision, and not one to do on a whim. A person or company that can do that easily is not one I want to work with.

Getting fired over the phone isn’t ideal, but what is? They had people spread out across the country, in offices and remote locations like me. How else were they supposed to do it? By email? This was probably the most conscientious way that it could have been done, given the circumstances.

So there I was, feeling betrayed, confused and lost; alternating between fear, anger, and disbelief so quickly that a manic-depressive on crack, riding a roller-coaster would have had a hard time keeping up with my emotions.

But the story does have a happy ending and a new beginning.

I quickly reached out on Twitter and Linkedin, letting people know that I had just lost my job, and asking if anyone knew of any positions available. The response was fast and overwhelming. It turns out that .Net developers with Ektron experience are very desirable. I quickly had an interview and a job offer with WSOL that I was happy to accept, and I start work in a few days.

I used to tell people that my job with Ektron was the one that Twitter helped me get, which is true, but I don’t think I would have gotten this new one as quickly as I did without being a presence on the social media platforms, or without the time I spent at Ektron.

I will always appreciate my time at Ektron, and getting to know the people that work there. It is a great company, with a good product, and spectacular people. I am still sad that I won’t be working there anymore, but that part of my life is over, and a new one is just getting started.