<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3575305097309371004</id><updated>2026-08-26T09:39:32.245-04:00</updated><category term="Developer Skills"/><category term="Front End Development"/><category term="Sitecore"/><category term="VueJS"/><category term="Developer Soft Skills"/><category term="FED First"/><category term="Management"/><title type='text'>Robert Guyett&#39;s Blog</title><subtitle type='html'>This is my blog where i go over all sorts of things i do. Anything from Web Development with Umbraco to Applications written in C++ or C# (.Net Framework) to my experiments with chip sets and learning how to weld.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.robertguyett.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.robertguyett.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Robert Guyett</name><uri>http://www.blogger.com/profile/01807518886746840835</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3575305097309371004.post-3512002781777892660</id><published>2020-03-25T14:41:00.000-04:00</published><updated>2020-03-25T14:41:04.374-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Developer Skills"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Sitecore"/><category scheme="http://www.blogger.com/atom/ns#" term="VueJS"/><title type='text'>Sitecore with VueJS: Reserved Attributes and Ignored Elements</title><content type='html'>&lt;h2&gt;
VueJS Strips Reserved Attributes on Ignored Elements&lt;/h2&gt;
&lt;div&gt;
Experience Editor is what makes Sitecore EXTRA amazing as a CMS. Don&#39;t get me wrong it has alot to offer but the &quot;oohhh ahhh WWoooWws&quot; happen when it starts showing off what it can do through the experience editor.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
One of the gotchas I ran into when connecting Sitecore and VueJS (and I&#39;m sure its the same for any framework that crawls the DOM to figure out what it should be doing) is that sometimes attributes can conflict with each other. In VueJS world it thinks its a vuejs attribute and will remove it from the dom and try to use it. Unfortunately even on ignored elements it will still strip its reserved attributes...&lt;br /&gt;
&lt;br /&gt;
Which breaks the experience editor with sitecore...&lt;/div&gt;
&lt;h3&gt;
The Problem&lt;/h3&gt;
&lt;div&gt;
VueJS removes Sitecore&#39;s attributes like &quot;key&quot; from the DOM even on elements that are marked to be ignored. There could be other conflicts but this is the one that got me.
&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
The Solution&lt;/h3&gt;
To make these conflicting elements not conflict, DUH!&lt;br /&gt;
&lt;br /&gt;
What we know:&lt;br /&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;There is no configuration to change sitecore to use different attributes and sitecore doesnt use scoped attributes e.g: namespace-attrname&lt;/li&gt;
&lt;li&gt;It would be a huge amount of effort and might ruin the upgrade path to try and alter such an integrated keyword in Sitecore&#39;s experience editor&lt;/li&gt;
&lt;li&gt;There is no configuration to change VueJS to use scoped keywords eg: vue-reservedkeywordname&lt;/li&gt;
&lt;li&gt;Vue has events that fire at the beginning of processing and just at the end of processing&lt;/li&gt;
&lt;li&gt;Vue has an ignoredElements configuration but some special attributes still get parsed out (like &quot;key&quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3&gt;
Approach:&lt;/h3&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Javascript module that alters reserved attributes on vue component&lt;/li&gt;
&lt;li&gt;It should not crawl over every single element...it needs to be focused and specialized for performance reasons&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;We&#39;ll only look at elements that have been marked to be ignored use the&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Because we don&#39;t really know all the conflicts we&#39;ll make the list of attributes expandable&lt;/li&gt;
&lt;li&gt;It will change the attribute names before VueJS processes its components and put them back to their original name&#39;s when its finished (this is only for elements vuejs shouldnt have been messing with in the first place)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3&gt;
Implementation:&lt;/h3&gt;
&lt;h4&gt;The Module:&lt;/h4&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: js&quot;&gt;/**
 * Author: Robert Guyett
 * Purpose: Resolves conflict with the &quot;key&quot; attribute between Sitecore&#39;s Experience Editor and VueJS
 * for Elements that VueJS should be ignoring
 */
import Vue from &#39;vue&#39;;

const reservedAttributes = [&#39;key&#39;];
const attrPrefix = &#39;data-&#39;;
export default {
    /**
     * Usage: Used just before vue is initialized in the root vueJS beforeCreate() event
     * This ads &quot;data-&quot; in front of any attribute marked as reserved by VueJS
     * NOTE: the reserved attributes doesnt tie into vuejs. its just an array of reserved attributes &quot;reservedAttributes&quot;
     */
    protectAttributes: () =&amp;gt; {
        let reservedElements = [...Vue.config.ignoredElements];
        reservedElements.forEach(reservedEl =&amp;gt; {
            [...document.querySelectorAll(reservedEl)].forEach(element =&amp;gt; {
                if(element.hasAttributes() === false) {
                    return;
                }

                let elAttrNames = element.getAttributeNames();
                reservedAttributes.forEach(attrName =&amp;gt; {
                    if(elAttrNames.includes(attrName)) {
                        // give the attribute a prefix
                        element.setAttribute(attrPrefix + attrName, element.getAttribute(attrName));
                    }
                });
            });
        });
    },
    /**
     * Usage: Used right after everything is mounted in the root VueJS mounted() event
     * This puts everything back the way it was
     */
    persistAttributes: () =&amp;gt; {
        let reservedElements = [...Vue.config.ignoredElements];
        reservedElements.forEach(reservedEl =&amp;gt; {
            [...document.querySelectorAll(reservedEl)].forEach(element =&amp;gt; {
                if(element.hasAttributes() === false) {
                    return;
                }

                let elAttrNames = element.getAttributeNames();
                reservedAttributes.forEach(attrName =&amp;gt; {
                    if(elAttrNames.includes(attrPrefix + attrName)) {
                        // set the attribute name back to the original value without the prefix
                        element.setAttribute(attrName, element.getAttribute(attrPrefix + attrName));
                    }
                });
            });
        });
    }
};

&lt;/pre&gt;
&lt;/div&gt;
&lt;h4&gt;Usage:&lt;/h4&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: js&quot;&gt;
import ignoredElementFix from &#39;./ignoredElementsFix&#39;

export default new Vue({
    el: &#39;#app&#39;,
    beforeCreate() {
        ignoredElementFix.protectAttributes();
    },
    mounted() {
        ignoredElementFix.persistAttributes();
    }
});
&lt;/pre&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.robertguyett.com/feeds/3512002781777892660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.robertguyett.com/2020/03/sitecore-with-vuejs-reserved-attributes.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/3512002781777892660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/3512002781777892660'/><link rel='alternate' type='text/html' href='http://www.robertguyett.com/2020/03/sitecore-with-vuejs-reserved-attributes.html' title='Sitecore with VueJS: Reserved Attributes and Ignored Elements'/><author><name>Robert Guyett</name><uri>http://www.blogger.com/profile/01807518886746840835</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3575305097309371004.post-1464299183448171159</id><published>2020-03-13T04:20:00.000-04:00</published><updated>2020-03-13T04:21:42.078-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Developer Soft Skills"/><category scheme="http://www.blogger.com/atom/ns#" term="Management"/><title type='text'>Soft Skills: Communicate on Another Level</title><content type='html'>&lt;h2&gt;
Communicate on Another Level&lt;/h2&gt;
Over the years I&#39;ve dedicated a lot of energy into being able to communicate and understand Project Managers, Product Owners, Programmers with various skill levels and specializations, and APIs. However, that list doesn&#39;t include anyone with a broader level of concerns. The past couple years I&#39;ve noticed I&#39;ve had to communicate more and more with Executives, Business Owners, and Managers of various levels more and more as my responsibilities increase and my impact on projects become greater. So the goal is to learn to communicate with people who care less about the inside workings of the project at hand and more about funding, timeline, overall health, and impact of multiple projects.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Ground Level&lt;/h4&gt;
I am a software engineer. I understand how code works and how to take an end goal and break it down into smaller tasks for success including the fine intricate details. I can organize code and explain how code works with other sets of code or services for a project or even multiple projects, and I can write documentation for code too. Unfortunately that is not what is really important on the business level.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
A Little More Management Scope&lt;/h4&gt;
On the business level we move from code concerns to management and profitability concerns. End goals need to be broken down into milestones for tracking progress, and impact for time and resources and less about completing three tasks to get X feature completed. Dependency issues transform from inter-dependency between code to inter-dependency between teams, partnerships, and events. In a sense, its the same concerns but with people/team/resource/business components instead of code components. At this level reporting justifications for initiatives becomes critical to success.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Upper Management&lt;/h4&gt;
A typical high level manager or C-Suit would never know first-hand what they could have saved in money and most likely isn&#39;t collecting metrics to find out an accurate ROI. They are trusting the reports of their subordinates. More importantly they need to understand the relationship of the metric of the report to the ROI. This is why time becomes the primary metric. Its easy and simple The faster its done equals the cheaper it is which means better ROI. Errors are a much better metric to track ROI for because alot of errors generally means alot of people are having terrible experiences. For clarity; we are not talking about engagement values. We are talking about the value of development speed vs quality. Is it justifiable to have higher quality development?</content><link rel='replies' type='application/atom+xml' href='http://www.robertguyett.com/feeds/1464299183448171159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.robertguyett.com/2020/03/soft-skills-communicate-on-another-level.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/1464299183448171159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/1464299183448171159'/><link rel='alternate' type='text/html' href='http://www.robertguyett.com/2020/03/soft-skills-communicate-on-another-level.html' title='Soft Skills: Communicate on Another Level'/><author><name>Robert Guyett</name><uri>http://www.blogger.com/profile/01807518886746840835</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3575305097309371004.post-2965633939710896916</id><published>2020-03-12T23:40:00.002-04:00</published><updated>2020-03-13T04:52:55.173-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Developer Skills"/><category scheme="http://www.blogger.com/atom/ns#" term="FED First"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Sitecore"/><category scheme="http://www.blogger.com/atom/ns#" term="VueJS"/><title type='text'>Sitecore with VueJS: Html Fragment Module</title><content type='html'>&lt;h2&gt;
Sitecore Module for VueJS&lt;/h2&gt;
I recently worked on a Sitecore 9.1 project where we got the chance to use a front end framework called VueJS. If you haven&#39;t had the chance to work with VueJS you should check them out&amp;nbsp;&lt;a href=&quot;https://vuejs.org/&quot;&gt;https://vuejs.org/&lt;/a&gt;. It was very nice to work with once we got through some of the kinks. One of those issues was that VueJS is driven by javascript (duh!)...not HTML....You know what likes to spit out HTML though? Sitecore!&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
The Challenge&lt;/h3&gt;
How do we make it so we can use Sitecore&#39;s placeholders and Sitecore&#39;s render methods with all of the nesting glory that can be done with them into a VueJS template?&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
The Solution&lt;/h3&gt;
To make a VueJS component that accepts the same formats Sitecore uses of course! Under the hood, Sitecore renders a begin tag element and an end tag element.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
What we know:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The most basic render method just takes those two properties and slaps them together to form a whole html element.&lt;/li&gt;
&lt;li&gt;VueJS utilizes a simple tree structure for components that requires each component have exactly one root element&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Approach:&lt;/h4&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;VueJS component that translates Sitecore render into a &quot;dynamic&quot; VueJS component (yes, i said that right)&lt;/li&gt;
&lt;li&gt;The &quot;dynamic&quot; component will be &quot;mounted&quot; to the current VueJS component (which is our Sitecore VueJS component...yes...component-ception!)&lt;/li&gt;
&lt;li&gt;To support anything that might get put between the begin tag and endtag we&#39;ll add some VueJS &amp;lt;slot&amp;gt; support&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Implementation:&lt;/h4&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js&quot;&gt;// Author: Robert Guyett
// Purpose: Workaround for Issue https://github.com/vuejs/vue/issues/7431
import Vue from &#39;vue&#39;;

const component = {
    functional: true,
    props: {
        html: {
            type: String,
            required: false,
            default: &#39;&#39;
        },
        begintag: {
            type: String,
            required: false,
            default: &#39;&#39;
        },
        endtag: {
            type: String,
            required: false,
            default: &#39;&#39;
        }
    },
    render(createElement, ctx) {
        let html = ctx.props.html;
        let addHtmlAsChild = true; // in case we ever want to add the html after the slot, we have granular control (maybe make it a property?) -rlg
        let begintag = ctx.props.begintag;
        let endtag = ctx.props.endtag;
        var generatedTemplate = &#39;&#39;;

        if(begintag === &#39;&#39;) {
            generatedTemplate = `${html}`;
            addHtmlAsChild = false;
        } else if(begintag !== &#39;&#39; &amp;amp;&amp;amp; endtag === &#39;&#39;) {
            generatedTemplate = `${begintag}`;
            addHtmlAsChild = false;
        } else {
            generatedTemplate = `${begintag}&lt;slot&gt;&lt;/slot&gt;${endtag}`;
            addHtmlAsChild = false;
        }

        let component = new Vue({
            template: `&lt;div&gt;
${generatedTemplate}&lt;/div&gt;
`
        });

        // add our default slot as a child node if applicable
        let defaultSlot = ctx.slots().default;
        if(typeof (defaultSlot) !== &#39;undefined&#39;) {
            component.$slots = { default: defaultSlot };
        }

        // initialize the component to get our virtual node
        var node = component.$mount()._vnode;
        node.children = node.children || [];

        // add html prop as a child if applicable
        if(addHtmlAsChild === true &amp;amp;&amp;amp; html !== &#39;&#39;) {
            var htmlNode = new Vue({
                template: html
            }).$mount()._vnode;
            node.children.push(htmlNode);
        }

        return node.children;
    }
};
Vue.component(&#39;html-fragment&#39;, component); // globally register this component
export default component;
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4&gt;
Final Notes:&lt;/h4&gt;
This is one way to get Sitecore&#39;s data into VueJS but it doesnt really allow us to manipulate that data like we would want to in the experience editor and do personalization with VueJS.</content><link rel='replies' type='application/atom+xml' href='http://www.robertguyett.com/feeds/2965633939710896916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.robertguyett.com/2020/03/sitecore-with-vuejs-html-fragment-module.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/2965633939710896916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3575305097309371004/posts/default/2965633939710896916'/><link rel='alternate' type='text/html' href='http://www.robertguyett.com/2020/03/sitecore-with-vuejs-html-fragment-module.html' title='Sitecore with VueJS: Html Fragment Module'/><author><name>Robert Guyett</name><uri>http://www.blogger.com/profile/01807518886746840835</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>