Times change – Closing the Sitecore chapter

As some of you have been aware… this blog once was a place for talking in an objective way about Sitecore. As the first world wide Sitecore MVP, I had tons of fun exploring the API and sometimes playing with pre-releases. This activity ended quite harsh when I joined Sitecore in 2008. I felt that putting my product thoughts in the blogosphere wouldn’t help the community. This was fed by a culture in the Microsoft world where you would innovate behind closed doors.

Now it’s late 2015 and lots of things have changed. First of all, even if Sitecore still wants to stay far away from transparency, they are forced to by industry leaders such as Microsoft, Amazon, Netflix and Facebook to keep an open dialogue. The pace of innovation has changed so much that ignoring your community in a strategic mistake. To survive you’ll have to discus your product offerings in the wide open to be and stay successful.

Much more has changed. For example, I just listed Microsoft as an industry leader… again. And ‘new’ names like Amazon and Netflix became technology industry leaders. The entire eco-system of the web, the big companies, the unicorns, all has changed. Technology has for sure changed the most. Look at me: I’m working today on a Mac, running Windows and OSX. And I love it. I can run literally any app virtualized using Docker… One of my IDEs is even written in Javascript (VS Code). And so on!

Much like the technical world, the customers in the web industry have been moving. About 2 years ago it became apparent to me. There are 2 interconnected metrics which dictate succes in the modern world: ability to respond and employee count(company size). The ones which aren’t able to respond and with huge amount of employees…. well they are doomed in the long run(think how Uber takes on the taxi industry). The ones who are small in size and able to respond quickly on market movements… They do well but struggle. They demand their environment to be ‘agile’. For example, they want to spin up a website and an entire marketing campaign to try out their new product proposal. Something the big enterprise can only dream off. You can imagine that the small, flexible ones aren’t looking at big ‘enterprisy’ systems at all.

The other 2 are in a transition. Either a transition to becoming big and inflexible or back to their core business: small and flexible. They might want to become big, but see the drawbacks. Or they want to focus again, but see issues with their shareholder who simply want more money. Nevertheless, they have to make a choice as vendors & suppliers don’t want to target companies who don’t make choices.

Sitecore has transformed with the industry to a place where it was mainly focused on the big and inflexible. But by doing that,  you become slower yourself. The facts that it took years to replace the back-end UI and the lack of concrete public cloud offerings are clear indicators that Sitecore struggled with it. But recently something has happened. Sitecore made a clear statement that it doesn’t want to become commodity. Over the course of July, Sitecore announced a global workforce cut. This reorganization should bring Sitecore back on track again: focused on the future, building the absolute best (web) products, adapting the latest on the web, competitive with Adobe, Eloqua, etc.

I personally was affected by the reorganization. I was made ‘redundant’. And that hurts a damn lot after all the years of hard work. Now, a few months later, I realize it’s for the better. Being blessed to work with some of the best in the industry, I have had the opportunity to get way beyond business savvy. And the personal side, I’ve been able to develop my personality in a very unique way, surrounded by a mix of people with many cultural backgrounds.

Almost two months ago I found a new employer in Xpirit. At Xpirit I work with the very best out of the industry including a few Microsoft Regional Directors, Microsoft MVPs and Xamarin MVPs and try to do software development right, just like it should be. We help ISVs and large companies to make a transition to the absolute latest and greatest in technology(Cloud, Azure, Enterprise Mobility, ALM, CD, etc). Currently I’m helping an ISV, active in the IoT space, to lift the quality of their software to the next level. Both with my handss in the code and on conceptual level :).

For the Sitecore community this means that I won’t be very active anymore. At Xpirit we do have customers running Sitecore,- but it’s definitely not our focus. We do of course  support Sitecore teams on ALM and Cloud transitions, so we touch Sitecore occasionally. But of course, feel free to reach out, happy to share my Sitecore knowledge! I’m still active on Twitter(@alexdegroot), but I just won’t be following #sitecore on a daily base anymore.

I sincerely hope that Sitecore will be able to get to a modern shape with a focus on innovative marketing products for their customers. It’s a hard journey and I won’t be surprised if it requires more restructurings and potentially acquisitions or being acquired. The company has the potential and the masterminds, now it needs to find the energy to execute upon it.

I want to thank all of my former colleagues and the entire Sitecore community for the great last 11 years. Thank you for the learnings, patience and politeness and most of all: thank you for the fantastic time. Keep rocking and keep innovating!

Hope to meet you in the future… For now: Have a fantastic 2016!

2015… The year of appreciation and privacy

Over the years I’ve worked a lot with our Ukrainian office and they have the very friendly habit to formally describe what their wishes for you on many occasions. The occurrence for doing this, ranges from Birthdays to Promotions to New Year.
At first I thought that this was way to formal, but I’ve recently really started to appreciate this. There’s no nicer gesture for an adult than putting your kindest wishes to words. Therefore, here are my formal wishes to you, slightly Ukrainian style:

Dear readers, fellow Sitecore community peep, colleague, friend or family member:
2014 was a fantastic year with lots of success and also those ineluctable (tiny) tears. We’ve been through it together and we’ve been standing strong to reach 2015 all together.
With this in mind, mat 2015 become the year where you achieve strong business success,  where you experience lots of love, in good health for you and your family and I sincerely hope that it becomes a year where you’ll be proud of. One you’ll tell about to your grandchildren when you’re old :-).

Happy new year!

Having the above in mind, I’d also make all of you aware where (in my eyes) 2015 is all about. Given that everyone is these days pretty much interconnected with his phone, his tablet, notebook, desktop, internet connected TV or even coffee machine… It’s time to start taking care of ourselves.

The world is quickly evolving in an internet first world and this basically means that when everything is connected to everything. The most horrible scenario we all can imagine is the Terminator vLast scenario where machines take over the data driven world. So we have to start taking care of ourselves. Especially Facebook is changing it’s policy again without really informing its users and given the significant increase in data hacks in the last 12 months. There are also positive signals, by the way.

The audience of this blogs is a technical audience who is mainly responsible for data driven websites. Sites where we gather (potential) customer information or information about our citizens. With this hunger for data, big responsibility is pushed on the shoulders of you, the engineer or architect. Since that you don’t want to phone number to be publically available to everyone… Please ensure your customers don’t experience the same issue.

And yes, dear architect or engineer, this is your job… You can’t push this shared away by hiring a security manager. It is the job of everyone in your team(from designer, to project manager, to manager, to….), we all should care about our shared security and privacy.

In the upcoming period, I’m going to spend more time on this topic and will try to inform you about what’s ongoing. For now, I leave you with the following 2 links for inspiration. I believe you can spend your first work hours in 2015 in a very smart way, by reading them.

A must read for everyone in the web industry…!

Marketing Punctuated Equilibrium

For all you, developers, techies, web analysts, designers, quality engineers and project managers in the internet industry. The following page is a real must read! As you can see on this picture, the marketing organizations are on loose ground. It’s time to help them, but before we can do that, we probably need to dive a bit into their world…


Quickly rebuilding the indexes of your DMS database

The easiest way to rebuild the indexes of your DMS database is done in the following way:

SQL Script
  2. GO
  3. –Set the fillfactor
  4. DECLARE @FillFactor TINYINT
  5. SELECT @FillFactor=80
  7. SELECT @StartTime=GETDATE()
  8. if object_id('tempdb..#TablesToRebuildIndex') is not null
  9. begin
  10. drop table #TablesToRebuildIndex
  11. end
  12. DECLARE @NumTables VARCHAR(20)
  13. SELECT
  14. s.[Name] AS SchemaName,
  15. t.[name] AS TableName,
  16. SUM(p.rows) AS RowsInTable
  17. INTO #TablesToRebuildIndex
  18. FROM
  19. sys.schemas s
  20. LEFT JOIN sys.tables t
  21. ON  s.schema_id = t.schema_id
  22. LEFT JOIN sys.partitions p
  23. ON  t.object_id = p.object_id
  24. LEFT JOIN sys.allocation_units a
  25. ON  p.partition_id = a.container_id
  26. WHERE
  27. p.index_id IN ( 0, 1 ) — 0 heap table , 1 table with clustered index
  28. AND p.rows IS NOT NULL
  29. AND a.type = 1  — row-data only , not LOB
  30. GROUP BY
  31. s.[Name],
  32. t.[name]
  33. SELECT @NumTables=@@ROWCOUNT
  34. DECLARE RebuildIndex CURSOR FOR
  35. SELECT
  36. ROW_NUMBER() OVER (ORDER BY ttus.RowsInTable),
  37. ttus.SchemaName,
  38. ttus.TableName,
  39. ttus.RowsInTable
  40. FROM
  41. #TablesToRebuildIndex AS ttus
  42. ORDER BY
  43. ttus.RowsInTable
  44. OPEN RebuildIndex
  45. DECLARE @TableNumber VARCHAR(20)
  46. DECLARE @SchemaName NVARCHAR(128)
  47. DECLARE @tableName NVARCHAR(128)
  48. DECLARE @RowsInTable VARCHAR(20)
  49. DECLARE @Statement NVARCHAR(300)
  50. DECLARE @Status NVARCHAR(300)
  51. FETCH NEXT FROM RebuildIndex INTO @TableNumber, @SchemaName, @tablename, @RowsInTable
  52. WHILE ( @@FETCH_STATUS = 0 )
  53. BEGIN
  54. SET @Status='Table '+@TableNumber+' of '+@NumTables+': Rebuilding indexes on '+@SchemaName+'.'+@tablename + ' ('+@RowsInTable+' rows)'
  55. RAISERROR (@Status, 0, 1) WITH NOWAIT  –RAISERROR used to immediately output status
  56. SET @Statement = 'ALTER INDEX ALL ON ['+@SchemaName+'].['+@tablename +'] REBUILD WITH (FILLFACTOR = '+CONVERT(VARCHAR(3), @FillFactor)+' )'
  57. EXEC sp_executesql @Statement
  58. FETCH NEXT FROM RebuildIndex INTO @TableNumber, @SchemaName, @tablename, @RowsInTable
  59. END
  60. CLOSE RebuildIndex
  61. DEALLOCATE RebuildIndex
  62. drop table #TablesToRebuildIndex
  63. Print 'Total Elapsed Time: '+CONVERT(VARCHAR(100), DATEDIFF(minute, @StartTime, GETDATE()))+' minutes'
  64. GO

This script is particular usable if you have a huge database since it optimizes the small ones first.

Example output:

Code Snippet
  1. Table 22 of 37: Rebuilding indexes on dbo.ReferringSites (40474 rows)
  2. Table 23 of 37: Rebuilding indexes on dbo.Locations (131276 rows)
  3. Table 24 of 37: Rebuilding indexes on dbo.Keywords (267301 rows)
  4. Table 25 of 37: Rebuilding indexes on dbo.UserAgents (337697 rows)
  5. Table 26 of 37: Rebuilding indexes on dbo.GeoIps (1573434 rows)
  6. Table 27 of 37: Rebuilding indexes on dbo.Cache_TrafficByDay (1755931 rows)
  7. Table 28 of 37: Rebuilding indexes on dbo.VisitorTags (1985036 rows)
  8. Table 29 of 37: Rebuilding indexes on dbo.AutomationStates (1987782 rows)
  9. Table 30 of 37: Rebuilding indexes on dbo.Profiles (3315763 rows)


Why Technical Stuff in your backlog matters

Inside Sitecore we work with Scrum. This simply means that we have the business prioritize business cases and technical teams try to implement them as good as possible. Over the years we’ve learned a lot about application development and one of those things was that we’ve to prioritize technical tasks in a similar fashion as business cases. Obviously these don’t go always hand in hand. A simple update of the Sitecore platform(for example Update-1 to Update-3) isn’t an obvious task for the business. In this particular case, there were only two new features in the platform:

  • New Channel Performance report inside the Insight Dashboards which shows which channels drive most value.
  • The Content Editor allows you now to display [shared] and [unversioned] to end users, to simplify translation projects

When we did the upgrade, we saw a decrease of performance on our production environment. I’ve heard from many sides internally the unfunded conclusion that ‘6.6 Update-3’ is a bad and slow release. Interesting thought… But reality was different. Last Monday we released another version of the website, but with the same version: 6.6 Update-3. In the end of the story, if you give people new features, you can never roll back.

The cause seemed to be in the combination of some new relative slow features, infrastructural problems and deprioritized technical tasks. Let’s focus on the last ones. Let’s assume that the Technical Task was something along the lines ‘optimize the custom item manager’. As a business user it’s quite hard to judge whether this adds value. A developer never tells you that it’s causing a 25% decrease of your website.

So what can you do to solve this challenge? I guess we all do know that we can do performance testing. But that in itself doesn’t change the mind of the business owner, who wants to have a quick time-to-market. The solution for that is to agree on the experience. A simple way is to decide together with your business owner what is allowed. For example: every server page needs to be generated and transferred in less than 500ms. This allows a browser load of less than 3 seconds.

Out of the sudden, this small technical task makes sense for the business user, because a developer talks his language. It’s a no-brainer but it happens a lot. It’s not related to the project process you’re using. Scrum has a Definition of Done while using Prince II, you’ll talk about deliverables.

Still it doesn’t justify refactoring of your code. It’s obvious that a business owner doesn’t see the value in that. It can even slow you down a lot! There are easy ways to show technical debt like this in relation to team performance, but you need to have a lot of tooling before you can make this visible. Most of the time you don’t have those, so let’s make it more concrete.

Refactoring is all based on making the same thing do the same job, but in a more maintainable way. If you’re doing code and performance optimizations at the same time, you’ll end up in the situation where the system performs well, but you’ve broken all functionality. So split it. Refactoring shouldn’t optimize stuff, but is polishing for you and your team mates.

Still it doesn’t justify why you’re doing it. But it makes it easier to explain to your boss or business owner: I made it maintainable.
Interestingly enough, that’s enough explanation for your boss or business owner. As part of your work, you’ve introduced 3 things:

  • Meeting the desired functionality (the feature works)
  • Meeting the desired quality standards (it performs well, it looks good, it validates, etc)
  • It’s ready to enhance further (because it’s maintainable)

So let’s assume they still don’t take it. Then make a list of the crappy stuff and explain in this list why you didn’t do it. Every time in the near future when you’ve to touch an area which is already build, show this list and show what you need to do to start working on it. In the end of the story it’s crappy code you’ve to work with.

Estimations will increase when you touch it again. The shock effect when you explain this is big. You can see it in the eyes of anyone who owns the budget where you are working with. You can go in the ‘told you so mode’. You’re allowed to do this once. Next time, propose to do it straight away, but as part as a simple flow when creating a new feature:

  1. First: Meet desired functionality
  2. Meet desired quality
  3. Meet desired code quality
  4. Do the check-in

Note: I make some shortcuts here. I do ignore all stuff like Test Driven Development, BDD, Pair Programming, etc. Why? Because they don’t add value to your business. Tests are cool for you. Because you like Green Checkboxes. The Business likes money. So what? Meet each other in the middle. Explain to them in a simplified way why you do stuff. Why Technical Debt matter. Why performance agreements matter. Make it visible. Fail on purpose. Learning is done by failing, not by showing I did according to the book. It’s sad but it’s damn true. But please, try to fail before you go to production Winking smile



From ECM-link to the right Email Campaign

In the operations around Sitecore.net we often get contacted by someone who has a problem with a link. Recent example of that is when we started to enable the CSRF-extensions for Sitecore 6.6(Update-3). All kinds of redirect problems were caught, but how to figure out to which exact mailing they are related?

Don’t worry, that’s easy… As long as you have database access… Smile

So let’s assume we have the following link:


The steps to get to the Campaign:

  1. Take the ec_as-query string parameter
  2. Execute the following script to the database. Where @guid is your ec_as-parameter

    DECLARE @guid VARCHAR(50)
    SET @guid = ‘00000000000000000000000000000000’

    SELECT [AutomationId]
      FROM [Sitecore_DMS].[dbo].[AutomationStates]
      WHERE [AutomationStateId] = CAST(
            SUBSTRING(@guid, 1, 8) + ‘-‘ + SUBSTRING(@guid, 9, 4) + ‘-‘ + SUBSTRING(@guid, 13, 4) + ‘-‘ +
            SUBSTRING(@guid, 17, 4) + ‘-‘ + SUBSTRING(@guid, 21, 12)

  3. Now you have the AutomationId which is the same as your Automation Plan in the back-end. You can simply search for the Item in the Content Editor.
  4. Once you’ve found this item, you can got to the Navigate Tab –> Links –> Referrers –> All campaigns that use this automation

So basically what have we done? We used the Automation State to get back to the original Campaign. Sounds easy doesn’t it Smile?

Windows Update for ASP.NET Vulnerability 2416728: Sitecore implications *Update*

As you could have been reading in my previous post, Sitecore’s major product Sitecore .NET Web Content Management System is affected by the ASP.NET Vulnerability 2416728. Today, Microsoft has released an update to all the Windows Update Services(WSUS and WU). You can find all the details in Scott Guthrie’s post.

What could potentially happen to your Sitecore installation when applying this patch?

  1. A couple of users get logged out. That’s only really notable for the user who use the check box ‘Remember me’. Just login again. That’s the deal. According to my checks on 6.2, this does not happen.
  2. Potentially you could get an exception for people who have a open session while updating Sitecore. According to my checks, this doesn’t happen.

So it seems that you can install this patch without any unexpected side effect. I’ve checked it on my machines and tested it there(so this is an unofficial Sitecore  statement). If we come across issue, we will let you know. If you come across issues, please let our support team know.

Update: Sometimes an ‘HttpException: Unable to validate data’ happens when people are already authenticated. I couldn’t reproduce this. But it seems to be there. In that case, please review this solution on SDN.

ASP.NET Vulnerability 2416728 and Sitecore

Sitecore’s major product Sitecore ASP.NET Web CMS is affected by the ASP.NET Vulnerability 2416728. Scott Guthrie describes all the nifty details about this threat in this post. Our Support-team has been working intensively with our Product team to get a well tested solution out. It’s available now. 

For more information, please review this article on SDN.

Sitecore, Webforms for Marketers, OMS and Dynamics CRM Campaign integration

Sitecore is moving a lot these days and releasing almost on a monthly base new and cool functionalities. Not everybody has the ability to work with Sitecore on a daily base an keep up with this new exciting functionality. So time for me to step in and guide you back to the highway by creating small and very focused blog posts. This is the first one about Webforms for Marketers and the Dynamics CRM Campaign Integration.

The following diagram shows how the CMS, OMS, Webforms for Marketers and Dynamics CRM Campaign Integration glue together: CRM Integratie

On top of the Sitecore Web CMS you can find the Sitecore Online Marketing Suite(OMS) which is used for gaining more details out of the visitor experience.

The Webforms for Marketers module is added on top of the OMS. It relies heavily on the OMS, so I’ve decided to add it there.
Eventually you can run this module without the OMS, but you’ll definitely not gain all the potential out of it.

For integration with MS Dynamics CRM, we have our new Dynamics CRM Campaign Integration module. This module consists of 2 parts:

  1. Save Actions: An extension to the Webforms for Marketers module. It allows any business user to import data into any CRM entity. All WYSIWYG. So no coding required.
  2. Security Provider: Share Contacts in Dynamics CRM as Users in Sitecore. This means that a contact in CRM can login into your Sitecore website for extranet purposes.

Let’s assume you want to start developing on a similar solution. Then it’s highly advisable for you to setup a sandbox environment. You need the following components:

Then you’re ready to rock!

So far so good for today. We’ve got plenty more to talk about. But that can wait for later.

Insert Options – Individual Items, Standard Values or Rules

A very common question I receive is that people don’t know anymore where to setup Insert Options. Especially with the new possibilities of the Sitecore 6.1 content management system.

Here’s my view on this:

  1. Individual item
    Rarely, you want to setup Insert Options on individual items. Something when you have a specific folder or section in your website, you might chose for this option. Keep in mind that this you always should have a valid reason.
    For example: For all my meta data I use the /Common/Folder template to store my item underneath. As these folders have only 1 specific setting(Insert Options), I’ve decided not to Subtemplate(create a new template and inherit from the Folder-template) the Folder-template, because of maintainability. Consider in that case Insert Option Rules.
  2. Branch Templates
    It’s a bad practice to set any Insert Options on Branch templates.
  3. Standard Values
    95% of the cases setup your Insert Options on Standard Values as it’s applied everywhere when you use the specific template.
  4. Insert Options Rules
    When you need to setup global conditions, like ‘All the items based on the Folder template containing the word ‘Blog’ should add the Blog Entry template as Insert Option’.
    We use it ourselves in the Marketing Center. We allow everybody to create folders, but we want them to create specific items underneath.
    Before setting up a rule, figure out if you can’t do it with Standard Values.

Trimming the list afterwards can always be done by settings up Insert Rules.
For an advanced Reference regarding these Content Infrastructure topics, please refer to Data Definition Reference.