How to index general link field - solr

I would like to know how Solr indexes general link field or do we need to create computed index field for this ?
I have a helper class which is inheriting from SearchResultItem and it has below index field.
[IndexField("Call To Action")]
public LinkField CallToAction { get; set; }
This field is a general link field in sitecore.
Below is the search code which retrieves all the Event_card values except CallToAction (i.e. Always null). if I convert the field type from Link to string , I get the entire general link raw value which is difficult to parse at view and make it editable through glass mapper.
if (result.TotalSearchResults != 0)
{
//Load Event card data to be displayed on page
var resultItems =
result.Select(c => new Event_Card
{
Headline = c.Document.Headline,
Start_Date=c.Document.StartDate,
Content=c.Document.ContentData,
Call_To_Action=c.Document.CallToAction // this is always null
});
}
Here is my Entity class related to Event_Card
Event_Card
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Team Development for Sitecore - GlassItem.tt", "1.0")]
[SitecoreField(IEvent_CardConstants.Call_To_ActionFieldName)]
public virtual Link Call_To_Action { get; set; }
IEvent_Card
[SitecoreField(IEvent_CardConstants.Call_To_ActionFieldName)]
Link Call_To_Action { get; set; }
public static partial class IEvent_CardConstants
{
public static readonly ID Call_To_ActionFieldId = new ID("4c296a05-d05f-47c5-8934-8801bec5be85");
public const string Call_To_ActionFieldName = "Call To Action";
}
Can anybody let me know How can I achieve this. If we need to use computed field , an example would be of great help.
Thanks in Advance !

I just quickly browsed and found useful link for you.
Map sitecore 8 general link field from Index
I think this Stack overflow question describes what you are saying and there is a link which might be helpful to you.

Related

Extending C1 Image Type with fields for Photographer etc?

Is it possible to extend the Image type in Composite C1 in order to get fields for photographer and other stuff?
(If not, I'll probably settle for json in the Description field.)
Could you please explain a little bit your question ? I would like to answer as per my understanding.
So in my notion you are trying to get user values using input fields regarding your image ? If yes then answer is yes you can through razor or any kind of function provided by CMS and for that you need to define parameters like this :
public DataReference<IMediaFile> ImageSource { get; set; }
public string altText { get; set; }
public string Title { get; set; }
[FunctionParameter(Label = "Short Description",
Help = "A short description ...",
DefaultValue = "(write your description here)",
WidgetMarkup = "<f:widgetfunction name='Composite.Widgets.String.TextArea' xmlns:f='http://www.composite.net/ns/function/1.0'><f:param name='SpellCheck' value='true' /></f:widgetfunction>")]
public string Description { get; set; }
So as Shown in above example using [FunctionParameter()] you can set label etc for the rest of the input parameters as well. So this will get the required info from the user and then with the help of razor you can create your <img> element. Let me know if we are on the same page as your question, then i think i can provide more light on the answer.
Hope this helps.
Thanks for reading this.

Conditionally include/exclude a field from being searched

We have a really wide index that we used for site-wide search of multiple pieces of content. I'd like to add a new field that only admins can search -- normal users shouldn't be able to search on it.
Currently, it looks like the only way to blacklist a search field is to use SearchParamaters.SearchFields, but this would require listing every single other field, which is not ideal, as our index grows occasionally, and would require remembering to add to this list.
Alternatively, we could use reflection to build this list, and we may go this route if it's our only option. Was just hoping there was another option I was overlooking.
While this isn't ideal, I ended up creating [Searchable] and [AdminSearchable] attributes, and decorated these on all the properties of our search document class:
[Searchable]
public string UserName { get; set; }
[Searchable]
public string UserDisplay { get; set; }
[AdminSearchable]
public string UserEmail { get; set; }
And then used these static fields to build the list of searchable fields, based on whether or not the current user is an admin:
private static readonly string[] _PublicSearchFeilds =
typeof(SearchDocument).GetProperties()
.Where(p => System.Attribute.IsDefined(p, typeof(SearchableAttribute)))
.Select(p => p.Name.ToLowerCamelCase()).ToArray();
private static readonly string[] _AdminSearchFeilds =
typeof(SearchDocument).GetProperties()
.Where(p =>
System.Attribute.IsDefined(p, typeof(SearchableAttribute)) ||
System.Attribute.IsDefined(p, typeof(AdminSearchableAttribute)))
.Select(p => p.Name.ToLowerCamelCase()).ToArray();
And passed this into SearchParameters.SearchFields.
There is currently no way to specify a list of fields to exclude from searches. Feel free to add this as a feature request on User Voice to help us prioritize.

How to use Dapper's SqlBuilder?

I can't find any documentation or examples I can follow to use the SqlBuilder class.
I need to generate sql queries dynamically and I found this class. Would this be the best option?
the best place to start is to checkout the dapper source code from its github repo and have a look at the SqlBuilder code. The SqlBuilder class is only a 200 lines or so and you should be able to make an informed choice on whether it is right for your needed.
An other option is to build your own. I personally went down this route as it made sense. Dapper maps select querys directly to a class if you name your class properties the same as your database or add an attribute such as displayName to map from you can use reflection to get the property names. Put there names and values into a dictionary and you can genarate sql fairly easy from there.
here is something to get you started:
first an example class that you can pass to your sqlbuilder.
public class Foo
{
public Foo()
{
TableName = "Foo";
}
public string TableName { get; set; }
[DisplayName("name")]
public string Name { get; set; }
[SearchField("fooId")]
public int Id { get; set; }
}
This is fairly basic. Idea behind the DisplayName attribute is you can separate the properties out that you want to include in your auto generation. in this case TableName does not have a DisplayName attribute so will not be picked up by the next class. however you can manually use it when generating your sql to get your table name.
public Dictionary<string, object> GetPropertyDictionary()
{
var propDictionary = new Dictionary<string, object>();
var passedType = this.GetType();
foreach (var propertyInfo in passedType.GetProperties())
{
var isDef = Attribute.IsDefined(propertyInfo, typeof(DisplayNameAttribute));
if (isDef)
{
var value = propertyInfo.GetValue(this, null);
if (value != null)
{
var displayNameAttribute =
(DisplayNameAttribute)
Attribute.GetCustomAttribute(propertyInfo, typeof(DisplayNameAttribute));
var displayName = displayNameAttribute.DisplayName;
propDictionary.Add(displayName, value);
}
}
}
return propDictionary;
}
This method looks at the properties for its class and if they are not null and have a displayname attribute will add them to a dictionary with the displayname value as the string component.
This method is designed to work as part of the model class and would need to be modified to work from a separate helper class. Personally I have it and all my other sql generation methods in a Base class that all my models inherit from.
once you have the values in the dictionary you can use this to dynamically generate sql based on the model you pass in. and you can also use it to populate your dapper DynamicParamaters for use with paramiterized sql.
I hope this helps put you on the right path to solving your problems.

Create an attribute programatically in EPiServer

This may be a very simple question but I'm very new to EPiServer, so pls help.
I'm working on the EPiServer Relate demo site. I want to progrmatically create a new attribute on Episerver.Common.Security.IUser type. I have created attributes using CMS edit mode Admin options. But I want to know how to do this in code.
You may want to use CommunityAttributeBuilder (https://github.com/Geta/Community.EntityAttributeBuilder) that is similar to PageTypeBuilder for CMS. Currently it's supporting CMS6, I'll commit v7 as soon I will finish testing.
By decorating your class properties with special attribute you will find those created in target site.
For instance:
[CommunityEntity(TargetType = typeof(IUser))]
public class UserAttributes : IClubUserAttributes
{
[CommunityEntityMetadata]
public virtual int AccessType { get; set; }
[CommunityEntityMetadata]
public virtual string Code { get; set; }
[CommunityEntityMetadata]
public virtual int EmployeeKey { get; set; }
[CommunityEntityMetadata]
public virtual bool IsAdmin { get; set; }
}
Library will scan all assemblies and look for types decorated with CommunityEntity attribute, if found one then properties will be scanned and those decorated with CommunityEntityMetadata attribute will be automatically created in DB.
It also supports strongly-typed interface over IUser type:
var metadata = user.AsAttributeExtendable<UserAttributes>();
metadata.AccessType = info.AccessType;
metadata.Code = info.Code;
metadata.EmployeeKey = info.EmployeeKey;
metadata.IsAdmin = info.IsAdmin;
More info about library could be found - http://world.episerver.com/Blogs/Valdis-Iljuconoks/Dates/2012/6/Community-Attribute-Builder-final/
More info about internals (if interested) could be found here - http://www.tech-fellow.lv/2012/06/when-you-need-something-stronger/
You need to use the AttributeHandler class.
Joel has written a great guide with example code here

Creating a Dynamic Linq filter over List<T>

Ok, I asked this question before, but deleted it as the way I went about describing my problem was wrong.
Firstly, let me state that Im creating a .NET3.5 Winforms app using C# and Plinqo (Professional Linq to Objects) as my ORM. Here's my situation: I have a DataGridview that is populated from a SortableBindingList<T> - in my case, formed from a List<Task> which is simply represented as follows:
public class Task {
public long TaskID { get; set; }
public string TaskDescription { get; set; }
public enumPriority TaskPriority { get; set; }
public DateTime DueDate { get; set; }
public double PercentageComplete { get; set; }
}
Now, I want to provide a Dialog to my user to allow him/her to Filter this list. I envision passing in a list of property names and associated DataType into the Dialog that I can use to populate a ComboBox. So the user will choose which property they want to query from the comboBox and based on the selection the appropriate comparers and UI control will be made available for the user to enter in thier criteria. Lastly, it will contain an AND/OR togglebutton at the end which the user can use to add additional criterion. Each criterion will be an object of type FilterItem as shown below:
public class FilterItem {
public string MappedPropertyName { get; set; }
public enumComparer Comparer { get; set; }
public object FilterValue { get; set; }
public enumOpertor Operator { get; set; }
}
After the user constructs his/her query, I intend to pass this as a List<FilterItem> back to my calling form, which can then iterate thru the list and allow me to filter the original List<Task>.
This is all fine, and something that I can put together with ease. But I want to make sure that the ACTUAL filter mechanism I go with is as strongly-typed as possible, and not using bulit up strings like in the Dynamic Query Library. (I used to do something similar previously with ADO.NET, DataViews and dynamically constructing a RowFilter string)
I've read up on Joseph Albahari's PredicatBuilder and an article on tomasp.net, but I seem heavily confused with it and expression trees in general.
I sincerely seek your assistance in helping me better understand these concepts, and how to go about using it up so that my intended architecture can work with it.
Much appreciation!
Additionally, I know I can do something like:
private SortableBindingList<Task> GetSortedTaskList()
{
List<Task> list = new List<Task>();
var query = DataUtil.GetUserTasks(xSys.Current.UserID);
if (/*description condition met*/)
{
query = query.Where(x => x.TaskDescription.Contains(FilterDesc));
}
if (/*due date condition met*/)
{
query = query.Where(x => x.DueDate >= FilterDate);
}
if (/*priority condition met*/)
{
query = query.Where(x => x.TaskPriority == FilterPriority);
}
...
list = query.ToList();
return new SortableBindingList<ArcTask>(list);
}
but this does not seem very scalable and 'dynamic'.

Resources