Custom Fields in pages...futureproof?
I want to add a new "shorttext" field to a page (you know what I mean) to store some simple data on the page level. So I'll do that in the API and expose it in my own custom control.
QUESTION is, when you guys start putting the UI in for custom fields in pages...will it just automatically start showing up in the page Title\Properties UI.
Anyone reading this, please vote on the issue: http://www.telerik.com/support/pits.aspx#/details/Issue=5449
Steve
Hi Steve,
Actually UI is the exact part we will be working on, as the current functionality does allow you to work with custom fields for pages programatically, the problem is that currently the Page type cannot persist values for these fields if you expose them in the UI.
All the best,
Boyan Barnev
the Telerik team
Great so I can go ahead and define a custom type on the page object and tweak it myself, then when you guys put in the UI bits it'll just magically showup right?
Hello Steve,
Thank you for pointing this out, I believe I understand your request better now. Well as you already know there is no concept of "deleting" a custom field in Sitefintiy, menaing that even if you remove a custom field the data is still preserved in the database, and you are later able to recreate the field. In the same line of reasoning if you already have the custom field there should be no problems adding it to the UI as well (please note that it's highly unlikely for the filed to pop up in Title and Properties before you actually set what interface for entering the data you'd like to have when adding the custom field form UI.
All the best,
Boyan Barnev
the Telerik team
So you're giving me the thumbs up, and even if I create the new field in the UI with the same name and the data is not there, I could always do a DB Update to copy the data from old column X to new column Y, correct?
Hello Steve,
Yes, that should work fine, however please stay in touch, as we haven't scheduled the feature implementation yet, as soon as we start working on it I can provide you with more details on the implementation framework we've agreed on. On a side note as we're trying to keep the UX consistent throughout the backend there shouldn't be any deviations from the current implementation.
Regards,
Boyan Barnev
the Telerik team
Ok, well I've made the field, and here's a simple control to update the "IconCssClass" for pages if anyone wants it...I made a new backend page under administration for the time being so this can't be edited publically :)
(Rename the file from .png to .zip)
Or if that doesn't work...
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PageIconManager.ascx.cs" Inherits="SitefinityWebApp.UserControls.PageIconManager.PageIconManager" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.NavigationControls" TagPrefix="sitefinity" %>
<
style
>
</
style
>
<
h1
id
=
"sfToMainContent"
class
=
"sfBreadCrumb"
>
Page Css Editor
</
h1
>
<
div
id
=
"setPolicyToolbar"
class
=
"sfAllToolsWrapper"
>
<
div
class
=
"sfAllTools"
>
<
div
id
=
"sfActions"
>
<
span
tabindex
=
"-1"
>
<
ul
>
<
li
class
=
"sfMainAction"
style
=
"padding-top: 5px"
>
<
asp:LinkButton
ID
=
"saveButton"
runat
=
"server"
CssClass
=
"sfLinkBtn sfSave"
OnClick
=
"OnSave_Click"
>
<
span
class
=
"sfLinkBtnIn"
>Save</
span
>
</
asp:LinkButton
>
<
asp:Label
ID
=
"saveLabel"
runat
=
"server"
/>
</
li
>
</
ul
>
</
span
>
</
div
>
</
div
>
</
div
>
<
div
class
=
"sfWorkArea"
>
<
h3
style
=
"padding:3px"
>This is a temp page to assign CSS Classes to a page until SF can put a UI in at a later date</
h3
>
<
telerik:RadTreeView
id
=
"pagesTreeView"
runat
=
"server"
Skin
=
"Sitefinity"
DataSourceID
=
"sitemapDS"
ExpandAnimation-Type
=
"None"
CollapseAnimation-Type
=
"None"
MultipleSelect
=
"false"
OnNodeDataBound
=
"onPages_NodeDataBound"
>
<
NodeTemplate
>
<
span
style
=
"padding-right: 5px"
><%# Eval("Title") %>:</
span
><
asp:TextBox
ID
=
"cssClassTextBox"
runat
=
"server"
/>
<
asp:HiddenField
ID
=
"pageIDField"
runat
=
"server"
Value='<%# Eval("PageId") %>' />
</
NodeTemplate
>
</
telerik:RadTreeView
>
<
sitefinity:SitefinitySiteMapDataSource
ID
=
"sitemapDS"
runat
=
"server"
ShowStartingNode
=
"false"
/>
</
div
>
<
script
type
=
"text/javascript"
>
</
script
>
using
System;
using
System.Collections.Generic;
using
System.Diagnostics;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Sitefinity;
using
Telerik.Sitefinity.Modules.Pages;
using
Telerik.Sitefinity.Pages;
using
Telerik.Sitefinity.Model;
using
Telerik.Sitefinity.Web;
using
Telerik.Web.UI;
using
Telerik.Sitefinity.Pages.Model;
namespace
SitefinityWebApp.UserControls.PageIconManager
public
partial
class
PageIconManager : System.Web.UI.UserControl
private
const
string
FIELD_PROPERTY =
"IconCssClass"
;
public
void
OnSave_Click(
object
sender, EventArgs e)
using
(PageManager manager =
new
PageManager())
foreach
(var node
in
pagesTreeView.GetAllNodes())
TextBox cssClassTextBox = node.FindControl(
"cssClassTextBox"
)
as
TextBox;
HiddenField pageIDField = node.FindControl(
"pageIDField"
)
as
HiddenField;
if
(
new
Guid(pageIDField.Value) != Guid.Empty)
PageData pageData = manager.GetPageData(
new
Guid(pageIDField.Value));
pageData.SetValue(FIELD_PROPERTY, cssClassTextBox.Text);
manager.SaveChanges();
saveLabel.Text =
"Saved At: "
+ DateTime.Now;
protected
void
Page_Init(
object
sender, EventArgs e)
pagesTreeView.DataBind();
public
void
onPages_NodeDataBound(
object
sender, RadTreeNodeEventArgs e)
PageSiteNode page = e.Node.DataItem
as
PageSiteNode;
RadTreeNode node = e.Node;
TextBox cssClassTextBox = node.FindControl(
"cssClassTextBox"
)
as
TextBox;
/*
var pg = App.WorkWith().Pages().Where(x => x.PageId == page.PageId).Get().SingleOrDefault();
var value = pg.Page.GetValue(FIELD_PROPERTY);
if(value != null)
cssClassTextBox.Text = pg.Page.GetValue(FIELD_PROPERTY).ToString();
*/
var pManager = PageManager.GetManager();
if
(page.PageId != Guid.Empty)
PageData pageData = pManager.GetPageData(page.PageId);
var value = pageData.GetValue(FIELD_PROPERTY);
if
(value !=
null
)
cssClassTextBox.Text = pageData.GetValue(FIELD_PROPERTY).ToString();
node.Expanded =
true
;
Hi Steve,
@Steve,
Your backend page code was a life saver. I have to make a few tweaks for stuff that seemingly changed in 5.3, but saved me a lot of time.
Hi Michael,
What tweaks did you have to make for 5.3 - I am finding that I am getting an error on the GetValue so perhaps this changed?
Cheers,
Seth
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MenuCssManager.ascx.cs" Inherits="SitefinityWebApp.ctsblogs.MenuCss.MenuCssManager" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.NavigationControls" TagPrefix="sitefinity" %>
<
style
>
</
style
>
<
h1
id
=
"sfToMainContent"
class
=
"sfBreadCrumb"
>
Page Css Editor
</
h1
>
<
div
id
=
"setPolicyToolbar"
class
=
"sfAllToolsWrapper"
>
<
div
class
=
"sfAllTools"
>
<
div
id
=
"sfActions"
>
<
span
tabindex
=
"-1"
>
<
ul
>
<
li
class
=
"sfMainAction"
style
=
"padding-top: 5px"
>
<
asp:LinkButton
ID
=
"saveButton"
runat
=
"server"
CssClass
=
"sfLinkBtn sfSave"
OnClick
=
"OnSave_Click"
>
<
span
class
=
"sfLinkBtnIn"
>Save</
span
>
</
asp:LinkButton
>
<
asp:Label
ID
=
"saveLabel"
runat
=
"server"
/>
</
li
>
</
ul
>
</
span
>
</
div
>
</
div
>
</
div
>
<
div
class
=
"sfWorkArea"
>
<
h3
style
=
"padding:3px"
>This is a temp page to assign CSS Classes to a page until SF can put a UI in at a later date</
h3
>
<
telerik:RadTreeView
id
=
"pagesTreeView"
runat
=
"server"
Skin
=
"Sitefinity"
DataSourceID
=
"sitemapDS"
ExpandAnimation-Type
=
"None"
CollapseAnimation-Type
=
"None"
MultipleSelect
=
"false"
OnNodeDataBound
=
"onPages_NodeDataBound"
>
<
NodeTemplate
>
<
span
style
=
"padding-right: 5px"
><%# Eval("Title") %>:</
span
><
asp:TextBox
ID
=
"cssClassTextBox"
runat
=
"server"
/>
<
asp:HiddenField
ID
=
"pageIDField"
runat
=
"server"
Value='<%# Eval("PageId") %>' />
</
NodeTemplate
>
</
telerik:RadTreeView
>
<
sitefinity:SitefinitySiteMapDataSource
ID
=
"sitemapDS"
runat
=
"server"
ShowStartingNode
=
"false"
/>
</
div
>
<
script
type
=
"text/javascript"
>
</
script
>
cs file
using
System;
using
System.Collections.Generic;
using
System.Diagnostics;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Sitefinity;
using
Telerik.Sitefinity.Modules.Pages;
using
Telerik.Sitefinity.Pages;
using
Telerik.Sitefinity.Model;
using
Telerik.Sitefinity.Web;
using
Telerik.Web.UI;
using
Telerik.Sitefinity.Pages.Model;
namespace
SitefinityWebApp.ctsblogs.MenuCss
public
partial
class
MenuCssManager : System.Web.UI.UserControl
private
const
string
FIELD_PROPERTY =
"MenuCssClass"
;
public
void
OnSave_Click(
object
sender, EventArgs e)
using
(PageManager manager =
new
PageManager())
foreach
(var node
in
pagesTreeView.GetAllNodes())
TextBox cssClassTextBox = node.FindControl(
"cssClassTextBox"
)
as
TextBox;
HiddenField pageIDField = node.FindControl(
"pageIDField"
)
as
HiddenField;
if
(
new
Guid(pageIDField.Value) != Guid.Empty)
PageData pageData = manager.GetPageData(
new
Guid(pageIDField.Value));
if
(pageData.NavigationNode.Attributes.ContainsKey(FIELD_PROPERTY))
pageData.NavigationNode.Attributes[FIELD_PROPERTY] = cssClassTextBox.Text;
else
pageData.NavigationNode.Attributes.Add(FIELD_PROPERTY, cssClassTextBox.Text);
manager.SaveChanges();
saveLabel.Text =
"Saved At: "
+ DateTime.Now;
protected
void
Page_Init(
object
sender, EventArgs e)
pagesTreeView.DataBind();
public
void
onPages_NodeDataBound(
object
sender, RadTreeNodeEventArgs e)
PageSiteNode page = e.Node.DataItem
as
PageSiteNode;
RadTreeNode node = e.Node;
TextBox cssClassTextBox = node.FindControl(
"cssClassTextBox"
)
as
TextBox;
/*
var pg = App.WorkWith().Pages().Where(x => x.PageId == page.PageId).Get().SingleOrDefault();
var value = pg.Page.GetValue(FIELD_PROPERTY);
if(value != null)
cssClassTextBox.Text = pg.Page.GetValue(FIELD_PROPERTY).ToString();
*/
var pManager = PageManager.GetManager();
if
(page.PageId != Guid.Empty)
PageData pageData = pManager.GetPageData(page.PageId);
string
val =
null
;
bool
hasVal = pageData.NavigationNode.Attributes.TryGetValue(FIELD_PROPERTY,
out
val);
if
(hasVal &&val !=
null
)
cssClassTextBox.Text = val;
node.Expanded =
true
;