2sxc dnn sql database and DNN search - 2sxc

If got this code in my razor template:
#using DotNetNuke.Entities.Modules
#using ToSic.Eav.DataSources
#using ToSic.SexyContent.Search
#functions
{
// Customize data not used - but it could often be used in search-demos, so I left it in
public override void CustomizeData()
{
// Don't customize anything, nothing to customize in this case
}
/// <summary>
/// Populate the search - ensure that each entity has an own url/page
/// </summary>
/// <param name="searchInfos"></param>
/// <param name="moduleInfo"></param>
/// <param name="startDate"></param>
public override void CustomizeSearch(Dictionary<string, List<ISearchInfo>> searchInfos, ModuleInfo moduleInfo, DateTime startDate)
{
// all we'll do is tell the search engine that the URL is a bit different for each found entity
foreach (var si in searchInfos["SearchIndex"])
{
si.QueryString = "?id=" + si.Entity.EntityId;
}
}
}
With this data queries:
But the dnn search is not picking up the items? I'm not seeing errors in the dnn logs when the search indexer runs. Do i have to use the Customize data function?
the query i run is this one:
SELECT [Hotel_ID] as EntityId
,[Hotel_ID]
,[Hotel_Name] + ' in ' + [City_Name] as EntityTitle
,[Hotel_Name]
,[Hotel_Address1]
,[Hotel_Address2]
,[Hotel_Address3]
,[Hotel_LAT]
,[Hotel_LNG]
,[Hotel_Website]
,[Hotel_Telephone1]
,[Hotel_Telephone2]
,[Hotel_Email1]
,[Hotel_Email2]
,[Hotel_Fax1]
,[Hotel_Logo]
,[Hotel_ZoomLevel]
,[City_Name]
,[Neighborhood_Name]
,[Departments_Name]
FROM [CI-HotelList]
Can anyone point me in the right direction?

Related

NopCommerce: Image size constraints

Using NopComm 3.90.
Is there a way in NopComm to set an image size constraint?
In Config -> Settings -> Media Settings, I can set the size of the images, but from what I gather this is setting default sizes of images? I need to set a hard constraint on the image sizes that our publishers will have to abide by. Thanks.
If you are using default picture upload in admin panel this method gets triggered during picture insert
/// <summary>
/// Validates input picture dimensions
/// </summary>
/// <param name="pictureBinary">Picture binary</param>
/// <param name="mimeType">MIME type</param>
/// <returns>Picture binary or throws an exception</returns>
public virtual byte[] ValidatePicture(byte[] pictureBinary, string mimeType)
{
using (var destStream = new MemoryStream())
{
ImageBuilder.Current.Build(pictureBinary, destStream, new ResizeSettings
{
MaxWidth = _mediaSettings.MaximumImageSize,
MaxHeight = _mediaSettings.MaximumImageSize,
Quality = _mediaSettings.DefaultImageQuality
});
return destStream.ToArray();
}
}
If you set "MaximumImageSize" in media settings nopCommerce will auto resize large images.
Setting a constraint to enforce a specific minimum picture size does not exists.
But you could easily create a plugin for that.

SDL Tridion 2011: Dynamically fill or add a metadata field using a C# TBB

Is it possible to set the value of a metadata field dynamically from a TBB? Or is it possible to dynamically add a metadata field that does not necessarily exist on a schema from a TBB?
The reason I want to do this is that I am using DD4T and I want to have the breadcrumb automatically added into the DD4T xml.
I have tried the following:
public override void Transform(Engine engine, Package package)
{
Initialize(engine,package);
var page = GetPage();
string output = page.OrganizationalItem.Title;
var parent = page.OrganizationalItem as StructureGroup;
while (parent != null)
{
output = GetLinkToStructureGroupIndexPage(parent) + Separator + output;
parent = parent.OrganizationalItem as StructureGroup;
}
// I tried this to dynamically add the field
//var metadata = page.Metadata.OwnerDocument.CreateElement("breadcrumb");
//metadata.InnerText = output;
//page.Metadata.AppendChild(metadata);
//I tried this to dynamically set an existing field on the schema
foreach (XmlNode xml in page.Metadata)
{
Log.Debug("Metadata field:" +xml.Name);
if(xml.Name == "breadcrumb")
{
xml.InnerText = output;
}
}
package.PushItem(Package.PageName, package.CreateTridionItem(ContentType.Page, page));
}
However, neither of these methods seem to work. Is this impossible?
DD4T has utility class FieldsBuilder with AddFields method where you can inject additional metadata. DD4T has a TBB which does update component metadata from Folder Metadata and it is called InheritMetadataComponent.
You could take a look at this here and you could implement the same:
http://code.google.com/p/dynamic-delivery-4-tridion/source/browse/trunk/dotnet/DD4T.Templates/InheritMetadataComponent.cs
FieldsBuilder.AddFields(component.MetadataFields, tcmFields, 1, false, mergeAction, Manager);
The easiest approach is to create a template class which implements DD4T.Templates.Base.BasePageTemplate. In that class, you implement the method TransformPage, which takes a DD4T page as its argument. You can access the 'TCM page' using the method GetTcmPage().
Example:
using TCM = Tridion.ContentManager.CommunicationManagement;
using Dynamic = DD4T.ContentModel;
public class MyTemplate : BasePageTemplate
{
protected override void TransformPage(Dynamic.Page page)
{
TCM.Page tcmPage = GetTcmPage();
string breadCrumbs = GetBreadCrumbs (tcmPage); // TODO: implement GetBreadCrumbs
Field f = new Field();
f.Name = "breadCrumbs";
f.FieldType = FieldType.Text;
f.Values.Add(breadCrumbs);
page.MetadataFields.Add("breadCrumbs", f);
}
}
page.MetadataFields.Add(name, field); should work if your template extends the DD4T.Templates.Base.BasePageTemplate
You can also take a look at the source of the Add inherited metadata to page TBB in DD4T, that also shows a way of adding Metadata which gets published to the broker.

Get last step in component wizard

C# Wizard control has the event ActiveStepChanged that is triggered when we move through the steps of the wizard. The current step is stored in the property called ActiveStepIndex. I need to retrieve the step immediately preceding the current ActiveStepIndex.
I'm trying this way but without results up to now:
ICollection s = wizTransferSheet.GetHistory();
IList steps = s as IList;
WizardStep lastStep = steps[steps.Count].Name;
Depending on how complex your wizard is, that can be tricky sometimes. You can't always use the ActiveStepIndex. Luckily, the wizard control logs a history of the steps visited, and you can leverage this to retrieve the last step that was visited:
You can use this function to get the last step that was visited:
/// <summary>
/// Gets the last wizard step visited.
/// </summary>
/// <returns></returns>
private WizardStep GetLastStepVisited()
{
//initialize a wizard step and default it to null
WizardStep previousStep = null;
//get the wizard navigation history and set the previous step to the first item
var wizardHistoryList = (ArrayList)wzServiceOrder.GetHistory();
if (wizardHistoryList.Count > 0)
previousStep = (WizardStep)wizardHistoryList[0];
//return the previous step
return previousStep;
}
Here's some sample code from one of our wizards. The wizard is pretty complex, and there is a lot of potential branching based on what the user does. Because of that branching, navigating the wizard can be a challenge. I don't know if any of this will be useful to you, but I figured it was worthwhile including it just in case.
/// <summary>
/// Navigates the wizard to the appropriate step depending on certain conditions.
/// </summary>
/// <param name="currentStep">The active wizard step.</param>
private void NavigateToNextStep(WizardStepBase currentStep)
{
//get the wizard navigation history and cast the collection as an array list
var wizardHistoryList = (ArrayList)wzServiceOrder.GetHistory();
if (wizardHistoryList.Count > 0)
{
var previousStep = wizardHistoryList[0] as WizardStep;
if (previousStep != null)
{
//determine which direction the wizard is moving so we can navigate to the correct step
var stepForward = wzServiceOrder.WizardSteps.IndexOf(previousStep) < wzServiceOrder.WizardSteps.IndexOf(currentStep);
if (currentStep == wsViewRecentWorkOrders)
{
//if there are no work orders for this site then skip the recent work orders step
if (grdWorkOrders.Items.Count == 0)
wzServiceOrder.MoveTo(stepForward ? wsServiceDetail : wsSiteInformation);
}
else if (currentStep == wsExtensionDates)
{
//if no work order is selected then bypass the extension setup step
if (grdWorkOrders.SelectedItems.Count == 0)
wzServiceOrder.MoveTo(stepForward ? wsServiceDetail : wsViewRecentWorkOrders);
}
else if (currentStep == wsSchedule)
{
//if a work order is selected then bypass the scheduling step
if (grdWorkOrders.SelectedItems.Count > 0)
wzServiceOrder.MoveTo(stepForward ? wsServicePreview : wsServiceDetail);
}
}
}
}

DevExpress LookUpEdit Behavior

I'm tearing my hair off for this amazing problem.
I'm binding 2 LookUpEdit from code:
MyBinding.DataSource = typeof(MyObject);
MyBinding.DataSource = _dataObject.GetMyList();
firstLookUp.DataBindings.Add("EditValue", MyBinding, "Code");
firstLookUp.Properties.DataSource = MyBinding;
firstLookUp.Properties.ValueMember = "Code";
firstLookUp.Properties.DisplayMember = "Code";
secondLookUp.DataBindings.Add("EditValue", MyBinding, "Info");
secondLookUp.Properties.DataSource = MyBinding;
secondLookUp.Properties.ValueMember = "Info";
secondLookUp.Properties.DisplayMember = "Info";
First problem is: Changing the value on one of the two LookUps not reflecting changing the other one! But im using the same BindingSource, isn't the position the same?
Another one is: They both populate automatically the columns, i dont want to show all columns, tried to remove, exception column not found, if i add, i get duplicate columns!
I don't get it!!!
Changing LookupEdit's EditValue is not directly bound to the BindingSource.Current position.
You have to use something like
lookUpEdit1.Properties.GetDataSourceRowByKeyValue(lookUpEdit1.EditValue)
If you want both LookupEdits linked you are probably better off setting the edit value of the one when the other is changed.
Secondly You should be able to clear the list of Columns like so:
lookUpEdit1.Properties.Columns.Clear();
lookUpEdit1.Properties.Columns.Add(new LookUpColumnInfo("FirstName"));
As said here
http://www.devexpress.com/Support/Center/p/B138420.aspx
http://www.devexpress.com/Support/Center/p/A2275.aspx
LookupEdit does update the Current Property of the BindingSource.
We use the following Code as a workaround:
/// <summary>
/// Wrapper around DevExpress.XtraEditors.LookUpEdit to fix bug with adjusting the BindingSources Current Position
/// </summary>
public sealed class LookUpEditWithDataSource : LookUpEdit
{
private bool firstCall = true;
/// <summary>
/// Called when the edit value changes.
/// </summary>
protected override void OnEditValueChanged()
{
base.OnEditValueChanged();
if (this.Properties.DataSource == null)
{
return;
}
if (this.BindingContext == null)
{
return;
}
if (this.firstCall)
{
this.firstCall = false;
// HACK
// starting and selecting the first item
// doesn't work so we change the position to the first item
this.BindingContext[this.Properties.DataSource].Position = 1;
}
this.BindingContext[this.Properties.DataSource].Position = this.Properties.GetDataSourceRowIndex(this.Properties.ValueMember, this.EditValue);
}
}

Asp.NET - Multiple Instances of AdRotator

I've created a master page that uses 3 instances of System.Web.UI.WebControls.AdRotator each backed by the same XML file of ad elements. For example,
<asp:adRotator AdvertisementFile="/ads.xml" Runat="server"/>
*** ads.xml ***
<Advertisements>
<Ad>
<ImageUrl>/Path/Banner.gif</ImageUrl>
<NavigateUrl>http://www.google.com</NavigateUrl>
<AlternateText>
The best search engine in the world!
</AlternateText>
<Impressions>3</Impressions>
</Ad>
</Advertisements>
The problem is on occasion the same ad will appear in 2 or more of the AdRotators at a given instant.
What's the best way to make the ads presented at any given time unique? One possibility is to separate the ads into 3 distinct XML files and assign each AdRotator a different file. However, that leads to a given ad always being in the same location that may or my not be the "premium" location on the page.
AdRotator wasn't designed to display a series of banners, so you can't prevent duplicates if you place multiple AdRotator controls on a Web Form and point them to the same AdvertisementFile.
The AdRotator is only designed to serve the most basic ad functionality. It's definitely not intended to compete with or replace a "real" ad-serving system. If you need anything more elaborate, you'll need to look into a third-party system or roll your own.
Although I second Rex M's recommendation of rolling out your own AdRotator because of its inherent limitations, there is a way to do this within the AdCreatedEvent of the rotator. For 3 or more rotators try the concept outlined at http://tinyurl.com/7rymect (must scroll to bottom of page to see answer). Otherwise, you could try something along these lines with 2 AdRotators on the page:
/// <summary>
/// First ad rotator control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void AdRotator_AdCreated(object sender, AdCreatedEventArgs e)
{
//Get displayed ad's id
int currentAd = (int)e.AdProperties["AdId"];
//Remove that ad from the list
TList<Banner> ads = GetBannerThatIsNotThisAdId(currentAd, AdRotator.KeywordFilter);
//Do we have an ad to display?
if (ads.Count > 0)
{
AdRotator1.DataSource = ads;
AdRotator1.DataBind();
}
else //nope, so hide 2nd control
{
AdRotator1.Visible = false;
}
}
public static TList<Banner> GetBannerThatIsNotThisAdId(int adId, string pCategory)
{
BannerService bannerService = new BannerService();
TList<Banner> banners = bannerService.GetAll();
Banner banner = bannerService.GetByAdId(adId);
banners.ApplyFilter(delegate(Banner b) { return b.Keyword.Equals(pCategory) && (b.IsActive.Equals(true)); });
banners.Remove(banner);
return banners;
}

Resources