2

I'm trying to add a new column to the GUI (I'm using Web8) which shows the schema name. I'm following this article which specifies that we should take care of refreshing/reloading of a component so we see the name when we first load the screen and later when we open up a component/page/etc (if not the value becomes empty in the column). So far I see the new column with a value but the reload part is not working. When I open (checkout automatically) a component the value in the grid is lost. In developer tools of Chrome there are no errors and in IE it says that "Unable to upgrade to type "GUIDataExtender.Extensions.UI.ExtendedComponent". So my guess is that it's not picking up my js files where that constructor is defined.

DataExtender.config

<?xml version="1.0" ?>

<Configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration/Merge"
               xmlns:cfg="http://www.sdltridion.com/2009/GUI/Configuration"
                             xmlns:ext="http://www.sdltridion.com/2009/GUI/extensions"
               xmlns:cmenu="http://www.sdltridion.com/2009/GUI/extensions/ContextMenu">

  <resources cache="true">
    <cfg:filters />
    <cfg:groups>
      <cfg:group name="GUIDataExtender.Extensions.UI.Model"
     merger="Tridion.Web.UI.Core.Configuration.Resources.DomainModelProcessor"
     merge="always">
        <cfg:domainmodel name="GUIDataExtender.Extensions.UI.Model">
          <cfg:fileset>
            <cfg:file type="script">/Scripts/ExtendedPage.js</cfg:file>
            <cfg:file type="script">/Scripts/ExtendedComponent.js</cfg:file>
          </cfg:fileset>
          <cfg:services />
        </cfg:domainmodel>
      </cfg:group>
      <cfg:dependencies>
        <cfg:dependency>Tridion.Web.UI.Editors.CME</cfg:dependency>
        <cfg:dependency>GUIDataExtender.Extensions.UI.Model</cfg:dependency>
      </cfg:dependencies>
    </cfg:groups>
  </resources>
  <definitionfiles />
  <extensions>
    <ext:modelextensions>
      <cfg:itemtypes>
        <cfg:itemtype id="tcm:16" implementation="GUIDataExtender.Extensions.UI.ExtendedComponent" />
        <cfg:itemtype id="tcm:64" implementation="GUIDataExtender.Extensions.UI.ExtendedPage" />
      </cfg:itemtypes>
    </ext:modelextensions>
    <ext:dataextenders>
      <ext:dataextender type="GUIExtension.GUIDataExtender, GUIDataExtender" name="SchemaNamExtender">
        <ext:description>Schema Name Extender</ext:description>
      </ext:dataextender>
    </ext:dataextenders>
    <ext:editorextensions>
      <ext:editorextension target="CME">
        <ext:editurls/>
        <ext:listdefinitions/>
        <ext:taskbars/>
        <ext:commands/>
        <ext:commandextensions/>
        <ext:contextmenus/>
        <ext:lists>
          <ext:add>
            <ext:extension name="SchemaNameExtender" assignid="SchemaNameExtender" insertbefore="FromPub">
              <ext:listDefinition>
                <ext:selectornamespaces/>
                <ext:columns>
                  <column xmlns="http://www.sdltridion.com/2009/GUI/extensions/List"
                              id="SchemaName" type="data" title="Schema Name"
                              selector="@ExtendedInfo" translate="String" />
                </ext:columns>
              </ext:listDefinition>
              <ext:apply>
                <ext:view name="DashboardView" />
              </ext:apply>
            </ext:extension>
          </ext:add>
        </ext:lists>
        <ext:tabpages/>
        <ext:toolbars/>
        <ext:ribbontoolbars/>
      </ext:editorextension>
    </ext:editorextensions>
  </extensions>
  <commands/>
  <contextmenus />
  <localization />
  <settings>
    <defaultpage/>
    <!-- /Views/Default.aspx</defaultpage> -->
    <navigatorurl/>
    <!-- /Views/Default.aspx</navigatorurl> -->
    <editurls/>
    <listdefinitions />
    <itemicons/>
    <theme>
      <path>theme/</path>
    </theme>
    <customconfiguration />
  </settings>
</Configuration>

ExtendedComponent.js

Type.registerNamespace("GUIDataExtender.Extensions.UI");

GUIDataExtender.Extensions.UI.ExtendedComponent = function ExtendedComponent(id) {
    Tridion.OO.enableInterface(this, "GUIDataExtender.Extensions.UI.ExtendedComponent");
    // test if initiative (from OME) exists
    var isInitiative = false;
    if (Tridion.OO.implementsInterface(this, "Tridion.OnlineMarketing.UI.InitiativeComponent")) {
        this.addInterface("Tridion.OnlineMarketing.UI.InitiativeComponent", [id]);
        isInitiative = true;
    } else {
        this.addInterface("Tridion.ContentManager.Component", [id]);
    }
    var p = this.properties;
    p.isInitiative = isInitiative;
    p.extendedInfo = undefined;
};

GUIDataExtender.Extensions.UI.ExtendedComponent.prototype.setDataFromList = function ExtendedComponent$setDataFromList(node, parentId, timeStamp) {
    var p = this.properties;

    if (!timeStamp || timeStamp > this.getTimeStamp()) {
        var tmp;

        if (tmp = $xml.getInnerText(node, "@ExtendedInfo")) {
            p.extendedInfo = tmp;
        }
    }

    if (p.isInitiative) {
        this.callBase("Tridion.ContentManager.InitiativeComponent", "setDataFromList", [node, parentId, timeStamp]);
    } else {
        this.callBase("Tridion.ContentManager.Component", "setDataFromList", [node, parentId, timeStamp]);
    }


};

/* get item icon */
GUIDataExtender.Extensions.UI.ExtendedComponent.prototype.getItemIcon = function ExtendedComponent$getItemIcon() {
    var icon = this.callBase(this.defaultBase, "getItemIcon");
    return icon;
};

GUIDataExtender.Extensions.UI.ExtendedComponent.prototype.getExtendedInfo = function ExtendedComponent$extendedInfo() {
    var p = this.properties;
    var xmlDoc;
    if (p.extendedInfo === undefined && (xmlDoc = this.getXmlDocument())) {
        //p.extendedInfo = $xml.selectSingleNode(xmlDoc, "/tcm:Page[@ExtendedInfo='true']") ? true : false;
        p.extendedInfo = $xml.selectSingleNode(xmlDoc, "/tcm:Page[@ExtendedInfo='true']") ? true : false;
    }
    return p.extendedInfo;
};


GUIDataExtender.Extensions.UI.ExtendedComponent.prototype.getListItemXmlAttributes = function ExtendedComponent$getListItemXmlAttributes(customAttributes) {
    var attribs = {};
    var p = this.properties;

    if (customAttributes) {
        for (var attr in customAttributes) {
            attribs[attr] = customAttributes[attr];
        }
    }
    //This adds my custom column back when the item is updated
    attribs["ExtendedInfo"] = p.extendedInfo;
    if (p.isInitiative) {
        return this.callBase("Tridion.ContentManager.InitiativeComponent", "getListItemXmlAttributes", [attribs]);
    } else {
        return this.callBase("Tridion.ContentManager.Component", "getListItemXmlAttributes", [attribs]);
    }
};

ExtendedPage.js

Type.registerNamespace("GUIDataExtender.Extensions.UI");

GUIDataExtender.Extensions.UI.ExtendedPage = function ExtendedPage(id) {
    Tridion.OO.enableInterface(this, "GUIDataExtender.Extensions.UI.ExtendedPage");
    // test if initiative (from OME) exists
    var isInitiative = false;
    if (Tridion.OO.implementsInterface(this, "Tridion.OnlineMarketing.UI.InitiativePage")) {
        this.addInterface("Tridion.OnlineMarketing.UI.InitiativePage", [id]);
        isInitiative = true;
    } else {
        this.addInterface("Tridion.ContentManager.Page", [id]);
    }
    var p = this.properties;
    p.isInitiative = isInitiative;
    p.extendedInfo = undefined;

};

GUIDataExtender.Extensions.UI.ExtendedPage.prototype.setDataFromList = function ExtendedPage$setDataFromList(node, parentId, timeStamp) {
    var p = this.properties;
    if (!timeStamp || timeStamp > this.getTimeStamp()) {
        var tmp;
        if (tmp = $xml.getInnerText(node, "@ExtendedInfo")) {
            p.extendedInfo = tmp;
        }
    }
    if (p.isInitiative) {        
        this.callBase("Tridion.ContentManager.InitiativePage", "setDataFromList", [node, parentId, timeStamp]);
    } else {        
        this.callBase("Tridion.ContentManager.Page", "setDataFromList", [node, parentId, timeStamp]);
    }


};

/* get item icon */
GUIDataExtender.Extensions.UI.ExtendedPage.prototype.getItemIcon = function ExtendedPage$getItemIcon() {
    debugger;
    var icon = this.callBase(this.defaultBase, "getItemIcon");
    return icon;
};

GUIDataExtender.Extensions.UI.ExtendedPage.prototype.getExtendedInfo = function ExtendedPage$extendedInfo() {
    var p = this.properties;
    var xmlDoc;
    if (p.extendedInfo === undefined && (xmlDoc = this.getXmlDocument())) {
        p.extendedInfo = $xml.selectSingleNode(xmlDoc, "/tcm:Page[@ExtendedInfo='true']") ? true : false;
    }
    return p.extendedInfo;
};

GUIDataExtender.Extensions.UI.ExtendedPage.prototype.getListItemXmlAttributes = function ExtendedPage$getListItemXmlAttributes(customAttributes) {
    var attribs = {};
    var p = this.properties;

    if (customAttributes) {
        for (var attr in customAttributes) {
            attribs[attr] = customAttributes[attr];
        }
    }
    //This adds my custom column back when the item is updated

    p.extendedInfo = this.getPageTemplateTitle();    
    attribs["ExtendedInfo"] = "PT: " + p.extendedInfo;

    if (p.isInitiative) {
        return this.callBase("Tridion.ContentManager.InitiativePage", "getListItemXmlAttributes", [attribs])
    } else {
        return this.callBase("Tridion.ContentManager.Page", "getListItemXmlAttributes", [attribs])
    }


};

/* get page template for the page */
GUIDataExtender.Extensions.UI.ExtendedPage.prototype.getPageTemplateTitle = function Page$getPageTemplateTitle() {
    var p = this.properties;
    if (this.getXmlDocument()) {
        p.pageTemplateTitle = $xml.getInnerText(p.xmlDoc, "/tcm:Page/tcm:Data/tcm:PageTemplate/@xlink:title") || null;
    }

    return p.pageTemplateTitle;
};

I've a Virtual Directory in IIS under Tridion website called "DataExtender" with a folder "Scripts" which has ExtendedComponent.js and ExtendedPage.js and the DataExtender.config file.

In System.config (located in WebRoot\Configuration) I've added this:

<editor name="DataExtender">
  <installpath>D:\Tridion\web\WebUI\Editors\DataExtender\</installpath>
  <configuration>DataExtender.config</configuration>
  <vdir>DataExtender</vdir>
</editor>

Then I've the c# part which I know is working as I see the column in the GUI with the correct value (but value is lost upon component/page opening).

Anything I'm missing?

Thanks in advance. Guillermo.

1

I think you'd have to create a commandset in your DataExtender.config whose implementation attribute is the JS object defined in ExtendedComponent.js. The dependency element is the name of the resource group that specifies the JS files that needs to be loaded when this extension is clicked on the UI.

<commands>
    <cfg:commandset id="Extensions.Commands.ExtendedComponent">
      <cfg:command name="ExtendedComponent" implementation="GUIDataExtender.Extensions.UI.ExtendedComponent"/>
      <cfg:dependencies>
        <cfg:dependency>GUIDataExtender.Extensions.UI.Model</cfg:dependency>
      </cfg:dependencies>
    </cfg:commandset>
</commands>

Similarly you'd have to create a command for ExtendedPage.js as well.

  • He's not extending a command, though :) – Peter Kjaer Jul 21 '17 at 8:09
  • Ah, didn't realize he was extending a model. Sorry! :) – Sabarish Senthilnathan Jul 27 '17 at 1:45
1

You are trying to extend Tridion.ContentManager.Component which is a model object -- yet you are configuring your extension as an editor extension. You should change your configuration to be a model extension instead.

0

I have encountered a similar issue earlier and found that namespace mismatch between the assembly and javascript has caused the js files not loaded properly witout any errors in the browser console.

[ControlResources("GUIDataExtender.Extensions.UI")]
<cfg:group name="GUIDataExtender.Extensions.UI.Model">
Type.registerNamespace("GUIDataExtender.Extensions.UI");

Hope this helps

  • Where should I put [ControlResources("GUIDataExtender.Extensions.UI")]? – polonskyg Apr 24 '17 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.