As seen in the Developer’s Guide documentation
Creating ASPX Master Pages, you can use <%=DocType%> as your doctype declaration in your master pages. The default value is
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. If you would like to change this, for instance to declare HTML5 (
<!DOCTYPE html>), you can do so in the code behind of your master page. In the
OnPreRender method of your master page codebehind (e.g., Root.master.cs), add a line defining
this.Doctype:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ltlTags.Text = HeaderTags;
// Declare the doctype as html5
this.DocType = "<!DOCTYPE html>";
}
-ag-
Regrettably, the nested macros are resolved too late for the condition. That is why the nested macros work for the branches of condition - (truevalue) and (falsevalue) parameters but not for the condition expression. If you want to compare two macros, please use custom macros. You can find a sample code here:
Macro expressions
Version 6 supports smarter system of macros: K#:
K# syntax
-hg-
In case your application runs on .NET version 4.0 the position should be fixed automatically. A combination of .NET 3.5 and browsers like Chrome or Safari causes the position on a page to be lost after postback.
-
The workaround is to use the AJAX update panel and check e.g. the Use update panel property in repeater based web parts.
-
If the update panel cannot be used for some reason, you can change the ~/App_Browsers/outputfilter.browser file and add the following code into the <browsers> section:
<browser refID="Safari1Plus">
<capabilities>
<capability name="supportsMaintainScrollPositionOnPostback" value="true" />
</capabilities>
</browser>
Please make sure that your master template, in case of Portal Engine it is file
~/CMSPages/PortalTemplate.aspx, contains the following property set to true:
<%@ Page … MaintainScrollPositionOnPostback="true" ..%>
-it-
The HttpOnly is a flag set on the server side when sending a cookie that instructs the browser to avoid giving client-side scripts access to that data. Prior to Kentico CMS 6.0 the default value of the
HttpOnly flag for all cookies generated by Kentico CMS was
false. Since Kentico CMS 6.0 this behavior has been changed in the way that all cookies have the
HttpOnly flag set to
true for security reasons. Therefore it might happen that some of your client-side scripts trying to read some cookie and working in the previous version are no longer working in Kentico CMS 6.0, as you would expect. If so, you have two options.
You can either use the overloaded version of the
CookieHelper.Setvalue method that accepts the HttpOnly value as an input parameter and set it to
false:
public static void SetValue (
string name,
string value,
string path
DateTime expires
bool? httpOnly
)
or change the following value in the
web.config file so that all cookies are sent with the
HttpOnly flag set to
false:
<httpCookies httpOnlyCookies="true"/>
Links to other resources: HttpOnly flag
-ml-
By default, document
event handlers (6.x) or custom
tree node handlers (5.x) are disabled for the staging module.
You can enable them by using the following web.config key:
<add key="CMSStagingUseTreeCustomHandlers" value="true" />
-mr-
A bit of customization is required to track all the downloaded files. The problem is that only
CMS.File document type downloads are tracked by default. However, you can change that by going to the file:
\CMSPages\GetFile.aspx.cs
Within this file, around line 451 there is the following condition:
if (IsLiveSite && (file.FileNode != null) && (file.FileNode.NodeClassName.ToLower() == "cms.file"))
You have to alter it to the following one so all files are logged, not only files attached to a CMS.File document:
if (IsLiveSite && (file.FileNode != null) )
You can also add only your document type, it's up to you:
if (IsLiveSite && (file.FileNode != null) && ((file.FileNode.NodeClassName.ToLower() == "cms.file")) II (file.FileNode.NodeClassName.ToLower() == "custom.documenttype")))
-bp-
The easiest way is to create a new link to the pages in CMS Desk by defining a new UI element. In this example we will use the UI Cultures module as an example. At first, navigate to
CMSModules/UICultures in your project folder. Please find all the *.cs files in the subfolders and change the inheritance of the pages from
SiteManagerPage to
CMSModalPage. Now, create a new element in CMS Site Manager / Development / Modules / CMS Desk / User Interface. Here add a new element with the following properties:
Display name: UI Cultures
Code name: UICulturesCMSDesk
Parent element: CMS Desk
Elemet is custom: true
Caption: UI Cultures
Target URL: ~/CMSModules/UICultures/Pages/Development/UICultures_Default.aspx
Now, when accessing CMS Desk a new UI element should be available with the caption “UI Cultures”.
-bp-
There may be some problem processing the last WebAnalytics log. Try to remove the oldest file off the ~\App_Data\CMSModules\WebAnalytics\ folder. This sometimes happens, but it will be fixed in 4.1 version. Some files aren't processed due to incorrect file names. Could you please also check if the scheduler runs correctly? Please go to Site Manager -> Administration -> Scheduled tasks, and try to manually run the "Analytics log processing" task.
In newer versions (5.5 and higher) you can simply use the query below to get the hotfix number from the database:
SELECT KeyValue, KeyName FROM CMS_SettingsKey WHERE KeyName = 'CMSHotfixVersion'
Otherwise you will have to simply determine it by the table below:
Hotfixes (build #) Hotfix version Build number
5.5 R2
5.5.31 R2 4216
5.5.30 R2 4206
5.5.29 R2 4202
5.5.28 R2 4191
5.5.27 R2 4188
5.5.26 R2 4181
5.5.25 R2 4175
5.5.24 R2 4164
5.5.23 R2 4160
5.5.22 R2 4150
5.5.21 R2 4147
5.5.20 R2 4136
5.5.19 R2 4129
5.5.18 R2 4125
5.5.17 R2 4115
5.5.16 R2 4108
5.5.15 R2 4104
5.5.14 R2 4097
5.5.13 R2 4090
5.5.12 R2 4083
5.5.11 R2 4073
5.5.10 R2 4070
5.5.9 R2 4059
5.5.8 R2 4051
5.5.7 R2 4045
5.5.6 R2 4041
5.5.5 R2 4031
5.5.4 R2 4027
5.5.3 R2 4020
5.5.2 R2 4014
5.5.1 R2 4006
5.5 R2 final / upgrade 3996
5.5
5.5.30 3999
5.5.29 3992
5.5.28 3981
5.5.27 3978
5.5.26 3971
5.5.25 3964
5.5.24 3957
5.5.23 3950
5.5.22 3943
5.5.21 3936
5.5.20 3926
5.5.19 3922
5.5.18 3912
5.5.17 3905
5.5.16 3901
5.5.15 3894
5.5.14 3887
5.5.13 3880
5.5.12 3873
5.5.11 3866
5.5.10 3859
5.5.9 3849
5.5.8 3842
5.5.7 3834
5.5.6 3828
5.5.5 3821
5.5.4 3817
5.5.3 3810
5.5.2 3803
5.5.1 3793
5.5.0 final / upgrade 3789
5.5.0 beta 3751
5.0
5.0.19 3784
5.0.18 3778
5.0.17 3771
5.0.16 3765
5.0.15 3758
5.0.14 3742
5.0.13 3733
5.0.12 3733
5.0.11 3722
5.0.10 3715
5.0.9 3708
5.0.8 3702
5.0.7 3693
5.0.6 3688
5.0.5 3681
5.0.4 3677
upgrade includes 5.0.3 3671
5.0.3 3670
5.0.2 3659
5.0.1 3656
5.0.0 final 3644
5.0.0 beta 3630
4.1
4.1.21 3667
4.1.20 3639
4.1.19 3639
4.1.18 3638
4.1.17 3631
4.1.16 3625
4.1.15 3617
4.1.14 3612
4.1.13 3603
4.1.12 3597
4.1.11 3590
4.1.10 3582
4.1.9 3576
4.1.8 3571
4.1.7 3561
4.1.6 3554
4.1.5 3552
4.1.4 3541
4.1.3 3537
4.1.2 3525
4.1.1 3523
4.1.0 3518
4.1.0 pre final 3513
4.0
4.0.15 3511
4.0.14 3505
4.0.13 3492
4.0.12 3492
4.0.11 3485
4.0.10 3481
4.0.9 3470
4.0.8 3464
4.0.7 3455
4.0.6 3436
4.0.5 3436
4.0.4 3432
4.0.3 3420
4.0.2 3397
4.0.1 3387
4.0.0 3328
-bp-
You can use a code like:
string output = ResHelper.RegExLocalize.Replace(input, LocalizedStringMatch);
where
input is a string with localization macros.
Then you need to specify
LocalizedStringMatch, for example:
/// <summary>
/// Match evaluator for the string localization
/// </summary>
/// <param name="m">Regular expression match</param>
private static string LocalizedStringMatch(System.Text.RegularExpressions.Match m)
{
string expression = m.Groups[1].ToString();
return ResHelper.GetString(expression, culture);
}
where
culture is a global string variable which contains a culture code (i.e. “en-US”).
-hg-
If you want to configure a web part to be visible on one page (e.g. Home), you can use a simple macro in the Visible web part property:
{%DocumentName|(equals)Home|(truevalue)true|(falsevalue)false%}
If you want to display the web part on the Home OR News document, you would need to use a nested macro. For example:
{%DocumentName|(equals)Home|(truevalue)true|(falsevalue){(1)%DocumentName\|(equals)New\|(truevalue)true\|(falsevalue)false%(1)}%}
You can also develop a custom macro instead of nesting macro expressions like:
Macro expressions
-hg-
For this purpose you can use following expression within your transformation:
<%# (CMS.CMSHelper.CMSContext.CurrentPageInfo.DocumentName.ToString() == Eval("MenuItemName").ToString() ? "curent page" : "not current") %>
It compares current document name with the value in the MenuItemName field. If they are equal the text after "?" sign is returned else you receive the text after ":". Please note it's only example, so you can adjust it to suit your needs.
If you want to resolve the
Inline controls for example on an ASPX template or in your custom web part, you can use the
CMS.ExtendedControls.ControlsHelper.ResolveDynamicControls(Control parent) method.
Please see this article by our CTO:
How to: Resolving the inline controls for more details.
-hg-
If you copy the document content from another language in CMSDesk, you can get data of original document in the
OnAfterInsertNewCultureVersion method of
CustomTreeNodeHandler like:
string sourceDocumentId = HttpContext.Current.Request.QueryString["sourcedocumentid"];
TreeProvider treeProvider = (TreeProvider)tree;
TreeNode sourceNode = DocumentHelper.GetDocument(Convert.ToInt32(sourceDocumentId), treeProvider);
You can set up the global property:
CMS.CMSOutputFilter.OutputFilter.CacheItems
The current value is "
username;sitename;lang;browser" but you can add the domain there like: "
username;sitename;lang;browser;domain"
You could add the custom code to for example:
~\App_Code\Global\CMS\CMSApplication.cs (the
AfterApplicationStart method).
-hg-
If you want to check for example
NewsTitle field if it contains the word:
“Home” you can use the if condition like this:
<%# (Eval("NewsTitle").ToString().Contains("Home")) ? "go home" : "go away" %>
The output text is “go home” if the NewsTitle contains “Home” substring and “go away” if not. Of course, you can use any Boolean expression before the question mark.
-hg-
You can use sample code below:
// Converts IP4 address to country name.
CMS.WebAnalytics.IP2CountryHelper ip2country = new CMS.WebAnalytics.IP2CountryHelper();
string country = ip2country.GetCountryByIp("<IP>");
Since version 5.5 of Kentico CMS IP2CountryHelper class is static. Therefore, you need to use following code instead:
string country = IP2CountryHelper.GetCountryByIp("<IP>");
The context menu is generated by the
UserContextMenu control located in
~\CMSAdminControls\ContextMenus\UserContextMenu.ascx.cs. To change the context menu edit the mentioned file according to your needs.
-bp-
You can encounter a problem that
<%# ResHelper.GetString(key) %> does not work.
Please use this format:
<%= ResHelper.GetString(key) %>
-hg-
This issue may occur after upgrade to version 5.0.
There should be following code in version 5.0 in ~\CMSInlineControls\ImageControl.ascx.cs (round the line 480):
imgParams.Url = GetFileIconUrl(this.Extension, "List");
However in version 4.x it looks like this:
imgParams.Url = ImageHelper.GetFileIconUrl(this.Extension, "List");
So it's possible that this line has been overwritten during import process of 4.1 web site into 5.0 version.
Please check if you use '%' character in your path for representation of sub-tree. If so, please remove it and specify full alias path of document instead. This macro is no longer supported by this method as it can be used in name of document (you can still use it in SelectNodes method though).
You can use sample code bellow:
using CMS.SiteProvider;
...
// Tree node
CMS.TreeEngine.TreeNode node = null;
// Tree provider
UserInfo ui = UserInfoProvider.GetUserInfo("administrator");
CMS.TreeEngine.TreeProvider tree = new CMS.TreeEngine.TreeProvider(ui);
// Get Single node specified by it`s ID
node = tree.SelectSingleNode(nodeId);
//Get GUID of attachment
Guid existingGuid = ValidationHelper.GetGuid(node.GetValue("FileAttachment"), Guid.Empty);
if (existingGuid != Guid.Empty)
{
// Get the attachment
AttachmentInfo existingAttachment =
am.GetAttachmentInfo(existingGuid, CMSContext.CurrentSite.SiteName);
}
You can use sample code bellow:
CMS.TreeEngine.TreeNode node = treeNodeObj as CMS.TreeEngine.TreeNode;
int documentCheckedOutVersionHistoryID = node.DocumentCheckedOutVersionHistoryID;
CMS.WorkflowEngine.VersionHistoryInfo whi = CMS.WorkflowEngine.VersionHistoryInfoProvider.GetVersionHistoryInfo(documentCheckedOutVersionHistoryID);
string comment = whi.VersionComment;
You may use the overloaded method with OrderBy parameter (see
API Reference for more details) but it sorts documents only within one document type. If you use more document types (classes) please use standard ASP.NET methods to sort the dataset. Please see the
MSDN documentation for more information.
Regrettably, SQL search doesn't support this functionality. You may use the Smart search feature (it is the new feature since 4.1 version) that natively support this functionality instead. Please see
Smart search chapter in Developer’s Guide for more details.
If you are using
extension-less ULRs for your web site, by default any postback adds an .aspxextension to the URL. You can disable this behavior using following key in your web.config file:
<add key="CMSUseExtensionOnPostback" value="false"/>
You can also use following sample code to get data (DataSet) from custom table:
CMS.SiteProvider.CustomTableItemProvider tp = new
CMS.SiteProvider.CustomTableItemProvider(CMS.CMSHelper.CMSContext.CurrentUser);
DataSet ds = tp.GetItems("CustomTableCodeName", "whereCondition", "OrderBy");
The 'dataObj' object can be both of DataClass and SimpleDataClass class in according to circumstances. Could you please check the class first and then re-type the object to appropriate class? Please see example at
http://msdn.microsoft.com/en-us/library/scekt9xw.aspx
This is caused by this setting doesn't affect directly the data of document. You can use OnAfterInsert method of CustomDataHandler instead (there comes SimpleDataClass object in dataObj parameter and it contains ClassName equal to 'ACLItem').
You can use following sample expression in WhereCondition parameter of SelectNodes or SelectDocuments method to get documents from category specified by its ID:
"DocumentID IN (SELECT DocumentID FROM CMS_DocumentCategory WHERE CategoryID = " + categoryId.ToString() + ")"
This issue is caused by UserCustomData is default column in CMS_User table (it's similar to CustomData field for document, please see '
Custom document data' section of DevGuide for more details) and is not related to custom field added to User system table anyhow (this field is added into CMS_User table as separate column). Please use following sample code instead:
userInfo.SetValue("NameOfField", value);
You can use sample code bellow to find out value of field (in this case called 'Name') of document currently processed by repeater and show/hide the custom user control accordingly (in this case show it if name is 'Kentico' and hide it otherwise):
<script runat="server">
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (this.Parent is IDataItemContainer)
{
IDataItemContainer cont = this.Parent as IDataItemContainer;
if (cont != null)
{
System.Data.DataRowView drv = (System.Data.DataRowView)cont.DataItem as System.Data.DataRowView;
if (drv != null)
{
this.myUserControl.Visible = (drv["Name"].ToString() == "Kentico");
}
else
{
Response.Write("Error: DataRowView is null");
}
}
else
{
Response.Write("Error: IDataItemContainer is null");
}
}
}
</script>
Since version 4.0 it's possible to refer to images with any extension in URL. You need to go through following procedure:
1) Please set 404 error handler as described in
extension less URL settings
2) You may need to set e.g.
.gif extension for your image (document) in:
CMS Desk -> Content -> Document -> Properties tab -> URLs -> Url extensions.
3) And then you need to set
'Document URL path' property. [
/some_folder for example]
You may develop your own control which uses standard ASP.NET validators. But when you insert the control on the page it fires the validation of your control’s fields if any button is pressed on the same page (for example the Search button in the Search box web part).
In this case, you would need to add this property to all buttons on the same page:
CausesValidation="false"
For example the declaration of Search button may look like:
<asp:Button CausesValidation="false" ID="btnGo" runat="server" OnClick="btnGo_Click" EnableViewState="false" />
If you want to add custom functionality for example after deleting a document type from the application you cannot use CustomDataHandler events for this purpose. You can register your custom event handler in ~/App_Code/Global/CMS/CMSApplication.cs file in AfterApplicationStart method using following sample code:
CMS.SettingsProvider.DataClassInfo.TYPEINFO.OnAfterDelete += new CMS.SettingsProvider.TypeInfo.ObjectActionEventHandler(TYPEINFO_OnAfterDelete);
void TYPEINFO_OnAfterDelete(CMS.SettingsProvider.IInfoObject infoObj)
{
throw new NotImplementedException();
}
Kentico CMS adds following code into master page when using Portal engine approach:
<link rel="shortcut icon" href="/<VirtualDirectoryName>/favicon.ico" />
If you want for some reason to use your custom path to your favicon or simply not want this link to be generated in your web pages, you can simply delete file "favicon.ico" from root of your web project folder and add your custom link to your favicon in CMS Desk -> Content -> click root -> Master Page tab section. Please note that this operation requires application restart.
Please open "Site Manager -> Development -> Web parts -> unfold Listing and viewers -> Image gallery -> Properties -> Thumbnail transformation" section, check the "" check box and click 'ok' to save changes. Then you should be able to edit 'Thumbnail transformation' in properties of Image gallery web part and modify it as you need.
You need to call ReloadData method of repeater after setting its properties in code-behind. You can also set 'DataBindByDefault' property of repeater (on aspx template) to false so the repeater won't bind data by default and will bind them only after you call ReloadData method.
You can use following sample code:
<img src="<%# GetDocumentUrl("fieldName", "") %>" />
You can use following function to find out if page with given full url exists in the site (it returns null if page doesn't exist):
CMS.PortalEngine.PageInfoProvider.GetPageInfoForUrl(...);
We are aware of this issue and want to deal with it in some of next versions. We are sorry for your inconveniences.
However, you may set the control properties in the Source mode of Visual studio - it is not restricting the functionality.
Please check if there is a
CMSPageManager control on your master page (.master). For more details please see:
devnet.kentico.com/docs/devguide/using_the_master_pages.htm.
If the same error persists please check also the
ScriptManager -
<asp:ScriptManager ID="manScript" runat="server" /> - some of our controls need it.
If you leave blank fields(which shouldn’t be empty according to document type definition) during the creation of new document, check it in and save it document will be stored with the empty field which is not correct in this case. The error saying you can’t save a null value to the database then occurs when you try to publish the document.
To solve this issue please open ~\CMSDesk\Content\edit.aspx file and put content of following methods: btnCheckIn_Click, btnReject_Click, btnApprove_Click into following condition:
// Validate the form first
if (formElem.BasicForm.ValidateData())
{
...
}
The inserted node is not available at that moment because the transaction on the SQL server is still running at the moment when the event fires.
You can try to ensure this in the following file which contains the code for creating new documents from the administration interface:
~\CMSDesk\Content\edit.aspx.cs