1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / URL Filtering in custom module

URL Filtering in custom module

4 posts, 0 answered
  1. Roberto
    Roberto avatar
    146 posts
    Registered:
    08 Feb 2008
    13 Aug 2011
    Link to this post
    Hi All,

    I have built a custom module and it i sitting nicely on a page.  One requirement is to filter the list view and i was thinking of doing this via a simple widget that simply post backs and changes the url to include the filter slash.

    for example:
    base url: http://localhost:1111/locations

    After a city is picked:
    http://localhost:1111/locations/london

    This will filter the results to show all locations that are in London (city is a custom property) and if they then select a location it simply goes to the direct page. 

    Now that the example is outlines, how do i go about doing this??, i tried updating the load data method in my master list view (and i knew it woudnt be this simple :)) but, as expected i get 404 errors.

    var query = this.Manager.GetLocations();
    if (masterDefinition.AllowUrlQueries.HasValue && masterDefinition.AllowUrlQueries.Value)
    {
        query = this.EvaluateUrl(query, "City", "City", this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
    }

    Help please :)

    Rob
  2. Roberto
    Roberto avatar
    146 posts
    Registered:
    08 Feb 2008
    16 Aug 2011
    Link to this post
    Yes, no, maybe?
  3. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    17 Aug 2011
    Link to this post
    Hi Roberto Modica,

    This is possible, however you have to build a custom URL evaluator for this. I am not aware of this City property so I have build a custom evaluator which works with string. I am basing my sample on the products catalog module. You can find sample code bellow:
    using System;
    using System.Text.RegularExpressions;
    using System.Web;
    using Telerik.Sitefinity.Pages.Model;
    using Telerik.Sitefinity.Web.UrlEvaluation;
     
    namespace ProductCatalogSample
    {
        class CityEvaluator : IUrlEvaluator<string>
        {
             
            #region IUrlEvaluator<int> Members
     
            public string BuildUrl(string data, UrlEvaluationMode urlEvaluationMode, string urlKeyPrefix)
            {
                switch (urlEvaluationMode)
                {
                    case UrlEvaluationMode.QueryString:
                        return QueryStringBuilder.Current.Add(String.Concat(urlKeyPrefix, queryStringIdentifier), data.ToString(), true).ToString();
                    default:
                        string result = string.Empty;
                        if (!string.IsNullOrEmpty(urlKeyPrefix))
                        {
                            result += "/!" + urlKeyPrefix;
                        }
                        if (data != string.Empty)
                        {
                            result += string.Concat("/"+queryStringIdentifier+"/", data);
                        }
                        result += string.Concat("/", QueryStringBuilder.Current.ToString());
                        return result;
                }
            }
     
            public string BuildUrl(string data, string urlKeyPrefix)
            {
                return this.BuildUrl(data, default(UrlEvaluationMode), urlKeyPrefix);
            }
     
            #endregion
     
            #region IUrlEvaluator Members
     
            public string BuildUrl(object data, Telerik.Sitefinity.Pages.Model.UrlEvaluationMode urlEvaluationMode, string urlKeyPrefix)
            {
                return this.BuildUrl((string)data, urlEvaluationMode, urlKeyPrefix);
            }
     
            public string BuildUrl(object data, string urlKeyPrefix)
            {
                return this.BuildUrl((string)data, urlKeyPrefix);
            }
     
            public string Evaluate(string url, string propertyName, Type contentType, Telerik.Sitefinity.Pages.Model.UrlEvaluationMode urlEvaluationMode, string key, out object[] values)
            {
                if (string.IsNullOrEmpty(url))
                    throw new ArgumentNullException("url");
     
                string urlKey = string.Concat(key, queryStringIdentifier);
     
                switch (urlEvaluationMode)
                {
                    case UrlEvaluationMode.QueryString:
                        string pageString = HttpContext.Current.Request.QueryString[urlKey];
                        if (!string.IsNullOrEmpty(pageString))
                        {
                            values = new object[] { pageString };
                        }
                        else
                        {
                            values = new object[] { };
                        }
                        return string.Empty;
                    case UrlEvaluationMode.UrlPath:
                    default:
                        MatchCollection matches = Regex.Matches(url, this.regularExpression);
                        if (matches.Count > 1)
                            throw new ArgumentException("More then one matches. URL string should contain only one match.");
                        string sVal = string.Empty;
                        if (matches.Count == 1)
                        {
                            
                            if ((string.IsNullOrEmpty(key) && !matches[0].Groups[urlPrefix].Success)
                                ||
                                (matches[0].Groups[urlPrefix].Success && matches[0].Groups[urlPrefix].Value == key))
                            {
                                sVal = matches[0].Groups[queryStringIdentifier].Value;
                            }
                        }
                        values = new object[] { sVal };
                        return string.Empty;
                }
            }
     
            public string Evaluate(string url, string propertyName, Type contentType, string key, out object[] values)
            {
                return this.Evaluate(url, propertyName, contentType, default(UrlEvaluationMode), key, out values);
            }
     
            public string Evaluate(string url, string propertyName, string key, out object[] values)
            {
                return this.Evaluate(url, propertyName, null, key, out values);
            }
     
            public void Initialize(System.Collections.Specialized.NameValueCollection config)
            {
                if (config == null)
                    throw new ArgumentNullException("config");
     
                this.regularExpression = config["regularExpression"];
     
                if (String.IsNullOrEmpty(this.regularExpression))
                    this.regularExpression = @"(/?!(?<" + urlPrefix + @">\w+)/)?(?<" + queryStringIdentifier + @">[\w|\-|_|\.]+)(?:/|\z)";
            }
     
            #endregion
     
            #region Private Fields
            private const string urlPrefix = "urlPrefix";
            private const string queryStringIdentifier = "city";
            private string regularExpression;
     
            #endregion
        }
    }


    Once you build the evaluator you must register it. It is best that you register it upon module installation. If you have already installed the module you can go to the SystemConfig file delete the version attribute for your module and restart the application. This will go over the installation process once more. Here is how you register this in the data config:
    public override void Install(SiteInitializer initializer)
    {
        base.Install(initializer);
     
        ...
        this.InstallCustomUrlEvaluators(initializer);
         
    }
     
    private void InstallCustomUrlEvaluators(SiteInitializer initializer)
    {
        var dataConfig = initializer.Context.GetConfig<DataConfig>();
        var citiesUrlEvaluatorConfig = new DataProviderSettings(dataConfig.UrlEvaluators)
        {
            Name = "City",
            Description = "Description",
            ProviderType = typeof(CityEvaluator)
        };
        if (!dataConfig.UrlEvaluators.ContainsKey("City"))
        {
            dataConfig.UrlEvaluators.Add(citiesUrlEvaluatorConfig);
        }
    }




    Greetings,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  4. Mike
    Mike avatar
    208 posts
    Registered:
    10 Dec 2007
    20 Feb 2012
    Link to this post
    Hi Radoslav,
    This doesn't seem to work for me.  When I implement the custom evaluator (I'm using as an example the Locations module from the SDK), the evaluator extracts the city (Austin, in my case) but doesn't seem to filter the results.  For example, in a querystring filter like this. I get "Austin" in sVal, but it doesn't seem to filter:
    http://localhost:50688/Locations?city=Austin
    values = new object[] { sVal };

    In my case, I need to filter by multiple values, such as City and State, or zipcode, or by latitude or longitude, which is why I chose to set it in the querystring.

    Anyway, when I debug this, it doesn't seem to affect the value in the query at all. An example of my code is:
    // check for filters on the locations query
    if (masterDefinition.AllowUrlQueries.HasValue && masterDefinition.AllowUrlQueries.Value)
    {
        query = this.EvaluateUrl(query, "Date", "PublicationDate", this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
        query = this.EvaluateUrl(query, "Author", "Owner", this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
        query = this.EvaluateUrl(query, "Taxonomy", "", typeof(LocationItem), this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
        query = this.EvaluateUrl(query, "City", "City", Telerik.Sitefinity.Pages.Model.UrlEvaluationMode.QueryString, this.Host.UrlKeyPrefix);
    }

    Any idea what I'm missing?

    Thanks,
    Mike




4 posts, 0 answered