URL Filtering in custom module

Posted by Community Admin on 04-Aug-2018 17:26

URL Filtering in custom module

All Replies

Posted by Community Admin on 13-Aug-2011 00:00

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: localhost:1111/locations

After a city is picked:
localhost:1111/.../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

Posted by Community Admin on 16-Aug-2011 00:00

Yes, no, maybe?

Posted by Community Admin on 17-Aug-2011 00:00

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

Posted by Community Admin on 20-Feb-2012 00:00

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




This thread is closed