What is wrong with this Widget Extension?

I have created a widget extension to return a simple array, but it won't work. Here it is:

namespace LocationData
{
    public class Location
    {

        public Array GetAllCountries()
        {
            string[] countries = { "United States", "United Kingdom", "Canada"};
            return countries;
        }

    }

    public class LocationWidgetExtension : IScriptedContentFragmentExtension
    {
        #region IScriptedContentFragmentExtension Members

        public string ExtensionName
        {
            get { return "Ibby_v1_LocationData"; }
        }

        public object Extension
        {
            get { return new Location(); }
        }

        #endregion

        #region IPlugin Members

        public string Name
        {
            get { return "GetLocationData"; }
        }

        public string Description
        {
            get { return "Get Location Data"; }
        }

        public void Initialize()
        {
        }

        #endregion
    }

}

And the Velocity Script

#set ($countries = $ibby_v1_LocationData.GetAllCountries())
#foreach($country in $countries)
    <span>$country</span>
#end

  • Have you enabled the extension on your site?  You also need to match the capitalization you defined in your extension.  It is defined as Ibby_v1_LocationData, but you are attempting to use it as ibby_v1_LocationData.

  • That worked, thanks. Also, can I return an array of objects? will that work?

  • I don't think there would be any reason an Array could not be returned.

  • I have modified the Widget Extension to return an array of objects, but they are not getting output as I want. Here's the code:

    namespace LocationData
    {
        public class Location
        {
    
            public Array GetAllCountries()
            {
                SqlDataAccess sd = new SqlDataAccess();
                SqlCommand sc = sd.GetCommand("EXEC ibby_GetAllCountries");
                DataTable dt = sd.Execute(sc);
                Item ct = new Item();
                List<Item> li = new List<Item>();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    ct = new Item();
                    ct.iso2 = dt.Rows[i]["iso2"].ToString();
                    ct.country = dt.Rows[i]["country"].ToString();
                    li.Add(ct);
                }
                return li.ToArray(); //dt.AsEnumerable().Select(r => r.Field<string>("country")).ToArray();
            }
    
        }
    
        public class LocationWidgetExtension : IScriptedContentFragmentExtension
        {
            #region IScriptedContentFragmentExtension Members
    
            public string ExtensionName
            {
                get { return "Ibby_v1_LocationData"; }
            }
    
            public object Extension
            {
                get { return new Location(); }
            }
    
            #endregion
    
            #region IPlugin Members
    
            public string Name
            {
                get { return "GetLocationData"; }
            }
    
            public string Description
            {
                get { return "Get Location Data"; }
            }
    
            public void Initialize()
            {
            }
    
            #endregion
        }
    
        public class Item
        {
            public string iso2;
            public string country;
        }
    
    }

    And here's the Velocity

    #set ($countries = $Ibby_v1_LocationData.GetAllCountries())
    #foreach($item in $countries)
        <span>$item.iso2</span>|<span>$item.country</span><br/>
    #end

    And this is what is being output:

    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country
    $item.iso2|$item.country

  • I would recommend returning a List<Item> rather than an Array.  Since the array is not typed, velocity does not know what the Objects inside it are.

  • I have changed it to return a List<Item>, but it is still not working.

  • Is the output the same?

    Have you tried using $core_v2_utility.Describe, that might help identify if your object is built as you expected it.

    #set ($countries = $Ibby_v1_LocationData.GetAllCountries())
    $core_v2_utility.Describe($countries)
    #foreach($item in $countries)
        $core_v2_utility.Describe($item)<br/>
    #end

  • Yes, the output is the same. Here's the output when using $core_v2_utility.Describe (note that I have changed the class name to CountryItem)

    [List-of-CountryItem]

    • [0] [CountryItem]
    • [1] [CountryItem]
    • [2] [CountryItem]
    • [3] [CountryItem]
    • [4] [CountryItem]
    • [5] [CountryItem]
    • [CountryItem]
    • [7] [CountryItem]
    • [CountryItem]
    • [9] [CountryItem]
    • [10] [CountryItem]
    • [11] [CountryItem]
    • [12] [CountryItem]
    • [13] [CountryItem]
    • [14] [CountryItem]
    • [15] [CountryItem]
    • [16] [CountryItem]
    • [17] [CountryItem]
    • [18] [CountryItem]
    • [19] [CountryItem]
    • [20] [CountryItem]
  • Are the properties of CountryItem being populated in C# code?  Correct capitalization on the property names when you request them?  $item.Iso vs $item.iso?

  • I believe so. Here's the C# code:

    namespace LocationData
    {
        public class Location
        {
    
            public List<CountryItem> GetAllCountries()
            {
                SqlDataAccess sd = new SqlDataAccess();
                SqlCommand sc = sd.GetCommand("EXEC ibby_GetAllCountries");
                DataTable dt = sd.Execute(sc);
                CountryItem ct;
                List<CountryItem> li = new List<CountryItem>();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    ct = new CountryItem();
                    ct.iso2 = dt.Rows[i]["iso2"].ToString();
                    ct.country = dt.Rows[i]["country"].ToString();
                    li.Add(ct);
                }
                return li; //dt.AsEnumerable().Select(r => r.Field<string>("country")).ToArray();
            }
    
            public List<RegionItem> GetRegionsInCountry(string iso2)
            {
                SqlDataAccess sd = new SqlDataAccess();
                SqlCommand sc = sd.GetCommand("EXEC ibby_GetRegionsInCountry " + iso2);
                DataTable dt = sd.Execute(sc);
                RegionItem ct;
                List<RegionItem> li = new List<RegionItem>();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    ct = new RegionItem();
                    ct.admin_code = dt.Rows[i]["admin_code"].ToString();
                    ct.admin_name = dt.Rows[i]["admin_name"].ToString();
                    li.Add(ct);
                }
                return li; //dt.AsEnumerable().Select(r => r.Field<string>("country")).ToArray();
            }
    
    
    
        }
    
        public class LocationWidgetExtension : IScriptedContentFragmentExtension
        {
            #region IScriptedContentFragmentExtension Members
    
            public string ExtensionName
            {
                get { return "Ibby_v1_LocationData"; }
            }
    
            public object Extension
            {
                get { return new Location(); }
            }
    
            #endregion
    
            #region IPlugin Members
    
            public string Name
            {
                get { return "GetLocationData"; }
            }
    
            public string Description
            {
                get { return "Get Location Data"; }
            }
    
            public void Initialize()
            {
            }
    
            #endregion
        }
    
        public class CountryItem
        {
            public string iso2;
            public string country;
        }
    
        public class RegionItem
        {
            public string admin_code;
            public string admin_name;
        }
    
    
    }