I'm having trouble getting my custom tokens to work with my ContentPart. My problem is the same as what is described here:
Is it possible to create an orchard autoroute using contents of a custom type property?
I have created my tokens:
namespace MyNS.Types.Providers
{
public class BioPartTokens : ITokenProvider
{
public BioPartTokens() {
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void Describe(dynamic context) {
context.For("Bio", T("Bio"), T("Tokens for the Bio content type"))
.Token("FirstName", T("FirstName"), T("First name of person."))
.Token("LastName", T("LastName"), T("Last name of person."));
}
public void Evaluate(dynamic context) {
context.For<BioPart>("Bio")
.Token("FirstName", (Func<BioPart, object>) (f => f.ContentItem.Parts.OfType<BioPart>().First().FirstName.ToLower()))
.Chain("FirstName", "FirstName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().FirstName.ToLower()))
.Token("LastName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().LastName.ToLower()))
.Chain("LastName", "LastName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().LastName.ToLower()))
;
}
}
}
My model:
namespace MyNS.Types.Models
{
public class BioPart: ContentPart<BioPartRecord>
{
public string FirstName {
get { return Record.FirstName; }
set { Record.FirstName = value; }
}
public string LastName
{
get { return Record.LastName; }
set { Record.LastName = value; }
}
public RoleInSchool RoleInSchool
{
get { return Record.RoleInSchool; }
set { Record.RoleInSchool = value; }
}
public bool IsBlogger {
get { return Record.IsBlogger; }
set { Record.IsBlogger = value; }
}
}
}
Though I've tried URL patterns with all of the following tokens, I've not been able to get a value back from the form that I've submitted:
{Content.Bio.FirstName}
{Content.BioPart.FirstName}
{Bio.FirstName}
{BioPart.FirstName}
No errors are being logged.
Related
I am having a bit of a problem using AutoMapper with some Configuration Elements.
I have the following classes:
public class SocialLinkSettingConfiguration : ConfigurationSection
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get { return this["name"] as string; }
set { this["name"] = value; }
}
[ConfigurationProperty("description", IsRequired = true)]
public string Description
{
get { return this["description"] as string; }
set { this["description"] = value; }
}
[ConfigurationProperty("url", IsRequired = true)]
public string Url
{
get { return this["url"] as string; }
set { this["url"] = value; }
}
[ConfigurationProperty("fontAwesomeClass", IsRequired = false)]
public string FontAwesomeClass
{
get { return this["fontAwesomeClass"] as string; }
set { this["fontAwesomeClass"] = value; }
}
[ConfigurationProperty("imageUrl", IsRequired = false)]
public string ImageUrl
{
get { return this["imageUrl"] as string; }
set { this["imageUrl"] = value; }
}
}
public class SocialLinkSettingConfigurationCollection : ConfigurationElementCollection
{
public SocialLinkSettingConfiguration this[int index]
{
get { return (SocialLinkSettingConfiguration)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(SocialLinkSettingConfiguration serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new SocialLinkSettingConfiguration();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((SocialLinkSettingConfiguration)element).Name;
}
public void Remove(SocialLinkSettingConfiguration serviceConfig)
{
BaseRemove(serviceConfig.Name);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
}
public class SocialLinkSetting
{
public string Name { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public string FontAwesomeClass { get; set; }
public string ImageUrl { get; set; }
}
I can create a mapping between SocialLinkSetting and SocialLinkSettingConfiguration just fine.
However, when I am trying to convert a list of SocialLinkSetting to SocialLinkSettingConfigurationCollection, I fail every time.
What I am trying to do is take a list of Social Links, and convert it to a single SocialLinkSettingConfigurationCollection object that has all of the SocialLinkSetting inside and converted to SocialLinkSettingConfiguration.
I can't seem to do this. Each time, it doesn't know how to convert List to the SocialLinkSettingConfigurationCollection, then add each of the items.
Any help would be greatly appreciated.
Thanks,
Ben
You can do something like this:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<SocialLinkSetting, SocialLinkSettingConfiguration>();
cfg.CreateMap<List<SocialLinkSetting>, SocialLinkSettingConfigurationCollection>()
.AfterMap((source, dest, resolutionContext) =>
{
dest.Clear();
source.ForEach(i => dest.Add(resolutionContext.Mapper.Map<SocialLinkSettingConfiguration>(i)));
});
});
I'm working in a new module for an orchard project. We've build a Company Part which is associated with an Address Part. What I'm eventually trying to get to is allowing users to enter various search criteria via the ui (non-admin interface), perform a search against all companies and return any matching results.
Where I'm struggling is how to build the query which allows me to include info from the associated address. So far I've only been able to successfully return results based on the CompanyPartRecord as opposed to the CompanyPart. The CompanyPartRecord obviously only contains the Address_Id of the associated AddressPart.
In essence I'm trying to get to something like this which will return an enumerable or list of companies which match the entered search criteria. There are more search options beyond zip so I'm looking for an extensible solution.
var query = _companyRepository.Table.AsQueryable();
if (!string.IsNullOrEmpty(Zip))
query = query.Where(c => c.Address.Zip == Zip);
var queryResult = query.ToList();
I've tried using both an IRepository (shown above) and with IContentManager such as the following:
var query = _contentManager.Query<CompanyPart, CompanyPartRecord>();
//var query = _contentManager.Query<CompanyPart>();
if (!string.IsNullOrEmpty(Zip))
query = query.Where(c => c.Address.Zip == Zip);
var queryResult = query.ToList();
Here's the actual Company and Address (Parts and Records):
public class CompanyPartRecord : ContentPartRecord
{
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual int Address_Id { get; set; }
public virtual string Phone { get; set; }
public virtual string OtherInformation { get; set; }
public virtual string Website { get; set; }
public virtual bool Inactive { get; set; }
// Keywords - Taxonomy
// Logo - associated part
// HasMissingData - derived
// NumberOfEmployees - associated part
}
public class CompanyPart : ContentPart<CompanyPartRecord>, ITitleAspect
{
internal readonly LazyField<AddressPart> AddressField = new LazyField<AddressPart>();
public string Name
{
get { return Record.Name; }
set { Record.Name = value; }
}
public string Description
{
get { return Record.Description; }
set { Record.Description = value; }
}
public AddressPart Address
{
get { return AddressField.Value; }
set { AddressField.Value = value; }
}
public string Phone
{
get { return Record.Phone; }
set { Record.Phone = value; }
}
public string OtherInformation
{
get { return Record.OtherInformation; }
set { Record.OtherInformation = value; }
}
public string Website
{
get { return Record.Website; }
set { Record.Website = value; }
}
public bool Inactive
{
get { return Record.Inactive; }
set { Record.Inactive = value; }
}
public string Title
{
get { return Name; }
}
}
public class AddressPartRecord : ContentPartRecord
{
public virtual string Street { get; set; }
public virtual string Street2 { get; set; }
public virtual string City { get; set; }
public virtual string CountyName { get; set; }
public virtual NationRecord State { get; set; }
public virtual string Zip { get; set; }
}
public class AddressPart : ContentPart<AddressPartRecord>
{
public string Street
{
get { return Record.Street; }
set { Record.Street = value; }
}
public string Street2
{
get { return Record.Street2; }
set { Record.Street2 = value; }
}
public string City
{
get { return Record.City; }
set { Record.City = value; }
}
public string CountyName
{
get { return Record.CountyName; }
set { Record.CountyName = value; }
}
public NationRecord State
{
get { return Record.State; }
set { Record.State = value; }
}
public string Zip
{
get { return Record.Zip; }
set { Record.Zip = value; }
}
}
I assume that you have a Content Type that contains both Parts (ie. named Company), if that is the case this should work:
var query = _contentManager.Query("Company").Where<AddressPartRecord>(x => x.Street == "query street");
var list = query.ToList();
The list contains the ContentItems filtered by street. Using .As() and .As() over the items of the list you get access to each part.
I would like to use nested list in my web.config. I see pieces of code that work, but not mine, i have an error when i try to read the configuration section :
System.Configuration.ConfigurationErrorsException : Élément non
reconnu IsochroneServicesTestImbrique'.
My config :
<IsochroneServicesTest>
<add name="TC">
<IsochroneServicesTestImbrique>
<add name="DEFAULT" path="success"/>
</IsochroneServicesTestImbrique>
</add>
</IsochroneServicesTest>
and the code :
[ConfigurationProperty("IsochroneServicesTest")]
[ConfigurationCollection(typeof(CollectionIsochrone), AddItemName = "add")]
public CollectionIsochroneType IsochroneServicesTest
{
get { return (CollectionIsochroneType)this["IsochroneServicesTest"]; }
set { this["IsochroneServicesTest"] = value; }
}
public class CollectionIsochroneType : ConfigurationElementCollection
{
public void Add(ProviderElement element)
{
base.BaseAdd(element);
}
protected override ConfigurationElement CreateNewElement()
{
return new IsochroneElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((IsochroneTypeElement)element).Name;
}
public IsochroneTypeElement this[int index]
{
get { return (IsochroneTypeElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public new IsochroneTypeElement this[string Name]
{
get { return (IsochroneTypeElement)BaseGet(Name); }
}
public int IndexOf(IsochroneTypeElement element)
{
return BaseIndexOf(element);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
}
public class IsochroneTypeElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("IsochroneServicesTestImbrique", IsRequired = true)]
[ConfigurationCollection(typeof(CollectionIsochrone), AddItemName = "add")]
public CollectionIsochrone IsochroneServicesImbrique
{
get { return (CollectionIsochrone)this["IsochroneServicesTestImbrique"]; }
set { this["IsochroneServicesTestImbrique"] = value; }
}
}
public class CollectionIsochrone : ConfigurationElementCollection
{
public void Add(ProviderElement element)
{
base.BaseAdd(element);
}
protected override ConfigurationElement CreateNewElement()
{
return new IsochroneElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((IsochroneElement)element).Name;
}
public IsochroneElement this[int index]
{
get { return (IsochroneElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public new IsochroneElement this[string Name]
{
get { return (IsochroneElement)BaseGet(Name); }
}
public int IndexOf(IsochroneElement element)
{
return BaseIndexOf(element);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
}
public class IsochroneElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("path", IsRequired = true)]
public string Path
{
get { return (string)this["path"]; }
set { this["path"] = value; }
}
}
Thanks for your help
You are getting that error because you are missing the declaration for IsochroneServicesTestImbrique in your <configSections> section. Also, at least one class must inherit from ConfigurationSection. See the example here.
I'm trying to use the Three20 TTPhotoViewController with MonoTouch. I've derived FacebookPhoto from TTPhoto and FacebookPhotoSource from TTPhotoSource and am now trying to invoke the TTPhotoViewController but I get the following exception when pushing the view controller:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: * -[NSPlaceholderString initWithFormat:locale:arguments:]: nil argument
I noticed that the monotouch bindings in this github project: https://github.com/mono/monotouch-bindings/tree/492f68c3c2007f0638452cc8a5a762556db224ba/Three20/binding were missing the photoAtIndex binding, so I added that and recompiled them, but I haven't been able to figure out why I am getting this exception.
Here is how I'm invoking the TTPhotoViewController:
List<Photo> photoList = FacebookGraphApi.Instance.GetAlbumPhotos(album.id);
List<FacebookPhoto> fbPhotoList = photoList.Select(x => new FacebookPhoto(x)).ToList();
var photos = new TTPhotoViewController();
photos.PhotoSource = new FacebookPhotoSource(fbPhotoList);
NavController.PushViewController(photos, true);
Here is the definition of the TTPhotoSource
class FacebookPhotoSource : TTPhotoSource
{
List<FacebookPhoto> _photoList;
public FacebookPhotoSource (List<FacebookPhoto> photoList)
{
_photoList = photoList;
int i = 0;
foreach (FacebookPhoto photo in photoList) {
photo.PhotoSource = this;
photo.Index = i++;
}
}
public override string Title {
get {
return "Facebook Photos";
}
set {
throw new NotImplementedException();
}
}
public override int NumberOfPhotos {
get {
return _photoList.Count;
}
}
public override int MaxPhotoIndex {
get {
return _photoList.Count -1;
}
}
public override TTPhoto PhotoAtIndex(int photoIndex)
{
return _photoList[photoIndex];
}
}
and here is the definition of the FacebookPhoto:
class FacebookPhoto : TTPhoto
{
Photo _photo;
public FacebookPhoto(Photo photo)
{
_photo = photo;
}
public override string Caption {
get {
if(_photo.name == null)
return "";
return _photo.name;
}
set {
throw new NotImplementedException();
}
}
public override TTPhotoSource PhotoSource { get; set; }
public override int Index { get; set; }
public override SizeF Size {
get {
return new SizeF(_photo.width, _photo.height);
}
set {
throw new NotImplementedException();
}
}
public override string URLForVersion (int version)
{
switch (version) {
case 4:
return _photo.picture;
default:
return _photo.source;
}
}
}
i am new in orchard module development.i create a module.when i try to save data.
i use this code fore save data
public ActionResult Create(FormCollection input)
{
var product = contentManager.New<ProductPart>("Product");
product.EmployeeName = input["EmployeeName"];
product.EmployeeFathersName = input["EmployeeFathersName"];
product.DOB = Convert.ToDateTime(input["DOB"]);
product.Email = input["Email"];
product.Address = input["Address"];
product.JoiningDate = Convert.ToDateTime(input["JoiningDate"]);
if (!ModelState.IsValid)
{
return View(product);
}
contentManager.Create(product);
return RedirectToAction("Index");
}
this class i use in Model
public class ProductRecord:ContentPartRecord
{
public virtual string EmployeeName { get; set; }
public virtual string EmployeeFathersName { get; set; }
public virtual DateTime DOB { get; set; }
public virtual string Email { get; set; }
public virtual string Address { get; set; }
public virtual DateTime JoiningDate { get; set; }
}
public class ProductPart : ContentPart<ProductRecord>
{
/*
public int Id
{
get { return Record.Id; }
set{Record.Id = value;}
}
*/
[Required]
public string EmployeeName
{
get { return Record.EmployeeName; }
set { Record.EmployeeName = value; }
}
[Required]
public string EmployeeFathersName
{
get { return Record.EmployeeFathersName; }
set { Record.EmployeeFathersName = value; }
}
[Required]
public DateTime DOB
{
get { return Record.DOB; }
set { Record.DOB = value; }
}
[Required]
public string Email
{
get { return Record.Email; }
set { Record.Email = value; }
}
[Required]
public string Address
{
get { return Record.Address; }
set { Record.Address = value; }
}
[Required]
public DateTime JoiningDate
{
get { return Record.JoiningDate;}
set { Record.JoiningDate = value; }
}
}
i use content type "Product" but when it goes orchard ContentCreateExtension in belows method
public static T New<T>(this IContentManager manager, string contentType) where T : class, IContent {
var contentItem = manager.New(contentType);
if (contentItem == null)
return null;
var part = contentItem.Get<T>();
if (part == null)
throw new InvalidCastException();
return part;
}
here i face var part is null that means it content part is null.
please help me....
Have you setup your migrations class?
i.e.
public class Migrations : DataMigrationImpl {
public int Create() {
SchemaBuilder.CreateTable("ProductRecord",
table => table
.ContentPartRecord()
.COLUMNS NEED TO BE SPECIFIED
);
ContentDefinitionManager.AlterTypeDefinition("Forum",
cfg => cfg
.WithPart("ProductPart")
.WithPart("CommonPart")
);
Also have you setup your repository?
i.e.
public class ProductPartHandler : ContentHandler {
public ProductPartHandler(IRepository<ProductPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
In addition to the Nicholas answer, I want to mention, that missing driver for the ProductPart can cause such error. Make sure, that you have at least empty driver defined.
public class ProductPartDriver : ContentPartDriver<ProductPart> {}
Just went through a similar situation, be sure that the handler class is declared as public.