Wrapped Editible Content Block Control?
We have a number of controls we've developed for our 3.7 site which are wrapped generic content controls. I can't figure out how to do this with Sitefinity 4.0. I had thought that I would put a ContentBlock control in the usercontrol's ascx page, but I don't know what to do with the code behind. In 3.7, we implemented the IGenericContent interface, and decorated the following property:
/// <summary>
/// The Wizzy-based content in the body of the pod.
/// </summary>
[Browsable(
false
)]
[WebEditor(
"Telerik.Cms.Engine.WebControls.HtmlContentEditor, Telerik.Cms.Engine"
)]
[TypeConverter(
typeof
(StringConverter))]
public
object
Content
get
return
bodyContent.Content;
set
bodyContent.Content = value.ToString();
Hi ,
The implementation you have now is not correct if we are talking for Sitefinity 3.7 edition. The way that the control should be wrapped there is shown here . The easiest way to achieve your goal in SF 4.0 is adding
HtmlField control inside the control template. The HtmlField wraps the RadEditor that you see when you open ContentBlock control
<%@ Control Language="C#" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sf" %>
<
sf:ResourceLinks
id
=
"resourcesLinks"
runat
=
"server"
>
<
sf:ResourceFile
Name
=
"Styles/Window.css"
/>
</
sf:ResourceLinks
>
<
sf:FormManager
ID
=
"formManager"
runat
=
"server"
/>
<
div
style
=
"width: 660px; overflow: hidden;"
>
<
sf:HtmlField
ID
=
"htmlEditor"
runat
=
"server"
Width
=
"99%"
Height
=
"370px"
EditorContentFilters
=
"DefaultFilters"
EditorStripFormattingOptions
=
"MSWord,Css,Font,Span,ConvertWordLists"
DisplayMode
=
"Write"
FixCursorIssue
=
"True"
>
</
sf:HtmlField
>
</
div
>
<
script
type
=
"text/javascript"
>
$("body").addClass("sfContentBlockDesigner");
</
script
>
Does anyone out there have a custom widget example that wraps a content block with a designer template? I've tried following the news widget example but really get nowhere.
Thanks in advance for any help!
Brian
You mean front-end wrapper to style it like this?
Shouldn't be needed in 4.0 as it's wrapped in .sfContentBlock by default
<
div
class
=
"sfContentBlock"
>
</
div
>
Hey Steve,
Thanks for the reply. Let me try & explain it this way....
In Sitefinity 3.7, sometimes our design would call for some copy content that for instance had some border wrapped around it. From a code stand point, I would never know where that border was needed, so I would create a control that wrapped around a generic content control, which made it easier for the end user to just drop the control in & start entering content.
If I remember correctly, in 4.0 I can assign a custom class around the content block, but that would require end users to remember to do that everytime they needed this custom border or whatever the design calls for. It also would require them to remember what the custom class name is.
So, I simply thought if I could wrap a content block in one of my custom controls, it would make life easier on the end user. Ultimately, I would like to learn how to wrap a image control & a content block control in my own custom control, but I just struggled trying to get the designer template working on the backend, & understanding what is needed to get the content to show up on the frontend.
Thanks again Steve for your time!
Brian
If I read this right....IMO in 4.0 ....your "wrapper" is a custom layout control :)
So user drops in the layout control which contains your styling...then they can put GC widgets into there
More flexible, less code :)
Yeah, your totally right with using the layout, that has saved me a ton of time.
Maybe I'm missing something here. If you take a look at the screenshot below, there is a PDF icon with some text to the right of it. Wrapped around that is some border. If the user simply drops a content block in the layout, I don't see a way how I would know to apply border & when not to apply border.
With a custom widget, everytime they dropped that on the page, I would know to apply border to that content block, without the user having to take extra steps to apply a custom class to the content block.
Maybe there is a different way of going about it that I'm not seeing?
You want to make a Custom Layout control as the wrapper, so it'd just be a single 100% layout (which could contain more if the user so chooses right). So there'd be a new layout control in the list called (I dont know) SitePDFBox, and they use that...this means you never have to hard code "areas" into your masterpage (more flexible)
And in the markup for THAT custom layout you wrap it in your class so you know that's your special callout box :)
Looks like they re-did or are re-doing the documentation so for the life of me I can't find the code on creating custom layouts, however I did make a bunch so if you're not sure I'll post the code here directly (let me know)
Yeah, after I replied to your last post, it clicked that maybe creating a custom layout control was the way to go. I started looking for some documentation on that too, haven't found any yet.
I you could post an example, that would be great.
Thanks again for your time today Steve.
Brian
Here ya go...
Code:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
Telerik.Sitefinity.Web.UI;
using
Telerik.Web.UI;
using
System.Web.UI;
using
System.Diagnostics;
using
System.Web.UI.WebControls;
using
System.Configuration;
using
System.ComponentModel;
using
Telerik.Sitefinity.Configuration;
using
Telerik.Sitefinity.Modules.Pages.Configuration;
using
Telerik.Sitefinity.Web.UI;
namespace
RandomSiteControls.Layouts
public
class
SimpleWrapperLayout : LayoutControl
protected
override
void
CreateChildControls()
base
.CreateChildControls();
public
override
string
AssemblyInfo
get
return
GetType().ToString();
set
base
.AssemblyInfo = value;
#region TEMPLATE
public
override
string
Layout
get
return
this
.CustomTempalate;
public
string
CustomTempalate =
"RandomSiteControls.Layouts.Views.SimpleWrapperLayout.ascx"
;
#endregion
<%@ Control Language="C#" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sitefinity" %>
<
div
class
=
"layoutWrapper"
>
<
div
id
=
"Div1"
runat
=
"server"
class
=
"sf_cols"
>
<
div
id
=
"Div2"
runat
=
"server"
class
=
"sf_colsOut sf_1cols_1_100"
>
<
div
id
=
"Div3"
runat
=
"server"
class
=
"sf_colsIn sf_1cols_1in_100"
>
</
div
>
</
div
>
</
div
>
</
div
>
Sweet! Thanks for the example Steve. I'll give this a try.
Hi Brian,
I wrapped the content block to put some extra divs and markup, to always put a rounded border around a content block. I achieved this by creating a control that inherits the content block and creating a new template putting my divs around <
asp:Literal
ID
=
"contentHtml"
runat
=
"server"
></
asp:Literal
>
using
System.Text;
using
Telerik.Sitefinity.Modules.GenericContent.Web.UI;
using
Telerik.Sitefinity.Web.UI.ControlDesign;
using
Telerik.Sitefinity.Web.UI.Fields;
namespace
Widgets
/// <summary>
/// Rounded version of the ContentBlock
/// </summary>
class
ContentBlockRounded : ContentBlock
/// <summary>
/// Gets the name of the embedded layout template.
/// </summary>
/// <value></value>
/// <remarks>
/// Override this property to change the embedded template to be used with the dialog
/// </remarks>
protected
override
string
LayoutTemplateName
get
return
layoutTemplateName;
private
const
string
layoutTemplateName =
"Widgets.Resources.Views.ContentBlockRounded.ascx"
;
<%@ Control Language="C#" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" Assembly="Telerik.Sitefinity" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.PublicControls" TagPrefix="sitefinity" %>
<
div
class
=
"rounded_colhead"
>
<
div
class
=
"tl"
></
div
><
div
class
=
"tr"
></
div
>
<
asp:Literal
ID
=
"contentHtml"
runat
=
"server"
></
asp:Literal
>
<
div
class
=
"bl"
></
div
><
div
class
=
"br"
></
div
>
</
div
>
<
sf:BrowseAndEditToolbar
ID
=
"browseAndEditToolbar"
runat
=
"server"
Mode
=
"Edit"
></
sf:BrowseAndEditToolbar
>
<
sitefinity:JavaScriptEmbedControl
runat
=
"server"
ID
=
"jQyeryLink"
ScriptEmbedPosition
=
"Head"
ScriptType
=
"jQuery"
></
sitefinity:JavaScriptEmbedControl
>
This is getting way too complicated... following the instructions here: www.sitefinity.com/.../how-to-create-a-widget.aspx for which is even more complicated than I need...
I can do a simple control with an input text box for say a Title. But I need input for the content. Like Brian, I have a simple 'template" that has a title and then content. See attached image. It is the getting the content like a Rad Editor that is the problem. I was able to do this the very old way using IGenericContent. Now I have to do the same thing for a new client in 4.0.. I don't have VS 10 and we don't have the Sitefinity Project Manager. I tried to follow the How to Create a Widget and I got it to work with a title only, as a User Control. When I went on to creating it as a Custom Control and then had to write the JQuery I got lost and frustrated. how can I take the basic user control from the 4.0 KB and add it so that the user can input text, graphics, etc.?
Thank you for any guidance.
Laura,
Here is what you will need to do to get this working:
Create a directory in the root of the site named controls. Inside that new controls directory, create a directory named JoinEditor. Inside the Join Editor folder should be two files seen below.
~/controls/JoinEditor/JoinEditor.cs
01.
using System;
02.
using System.Collections.Generic;
03.
using System.Linq;
04.
using System.Web;
05.
using Telerik.Sitefinity.Modules.GenericContent.Web.UI;
06.
using Telerik.Sitefinity.Web.UI.ControlDesign;
07.
using Telerik.Sitefinity.Web.UI.Fields;
08.
09.
namespace SitefinityWebApp.controls.JoinEditor
10.
11.
public class JoinEditor : ContentBlock
12.
13.
protected override string LayoutTemplateName
14.
15.
get
16.
17.
return layoutTemplateName;
18.
19.
20.
21.
private const string layoutTemplateName = "SitefinityWebApp.controls.JoinEditor.JoinEditor.ascx";
22.
23.
01.
<%@ Control Language="C#" %>
02.
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" Assembly="Telerik.Sitefinity" %>
03.
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.PublicControls" TagPrefix="sitefinity" %>
04.
05.
<
div
id
=
"ContentWrapper"
>
06.
<
asp:Literal
ID
=
"contentHtml"
runat
=
"server"
></
asp:Literal
>
07.
</
div
>
08.
09.
<
sf:BrowseAndEditToolbar
ID
=
"browseAndEditToolbar"
runat
=
"server"
Mode
=
"Edit"
></
sf:BrowseAndEditToolbar
>
10.
<
sitefinity:JavaScriptEmbedControl
runat
=
"server"
ID
=
"jQyeryLink"
ScriptEmbedPosition
=
"Head"
ScriptType
=
"jQuery"
></
sitefinity:JavaScriptEmbedControl
>
Thank you very much Brian!
I suppose I will have to be able to access the Sitefinity Project manager and edit in VS from there because when I tried the code and put the control on the page it said “Could not load file or assembly 'SitefinityWebApp' or one of its dependencies. The system cannot find the file specified” Sitefinity 4.0 is now a Web Application.
From past versions I was able to just download the files i needed and open it up in VS 2008. Then upload my files. But I suppose now I have to -- "Open your Sitefinity project by starting the Sitefinity Project Manager and clicking Edit in Visual Studio.” 2010
@Laura
You dont really NEED the project manager once it's created... :)
1) Every new project created has the .proj file in its root, and when clicked on should open visual studio. I'm not sure why you don't have access to 2010 where you work, but MS has the Free Visual Studio Express 2010 which I suppose could load the solution. It uses some features like WWF4 which are VS2010 exclusive.
2) Josh has a post where you can convert the Web Application project into a Web Site project HERE so it'll work the same as 3.x
Steve
Thanks Steve I was looking for that link. We are a small shop but will now be getting VS 2010!
I have an example of what you are looking for...i had the same thing...and spent hours on hours getting it to work in 4.0...
It won't let me attach my code so if you want the code send me a email at:
jtainter@dynastyrogues.com
I think my biggest misunderstanding is that I need to run the site on my local machine... And so launching VS from the project manager would make sense. It didn't make sense to me because in the past I have just uploaded my controls/classes to the server and added it in the web.config and voila. But now I have to download the entire web application to my local machine.
Also, I don't even see SitefinityWebApp.dll in the bin folder so maybe it has not been set up right anyway?
SitefinityWebApp.dll is what gets generated when you compile the site in 2010, it'll show up in the bin folder automatically
Converting to a website project should be what you want I believe...webapps are very much tied to compilation on a machine...but you can still load the thing in IIS and run it from there on your box, you dont need the built in casini asp development webserver.
Hi Laura,
Sitefinity 4.0 is shipped as a standard web application project, but you can always convert it to a web site
www.sitefinity.com/.../followup_converting_sitefinity_4_web_application_projects_to_web_site_projects.aspx
The way that Sitefinity 4.0 webapplication/web project is loaded and managed through VS is the same as way you mange each other standard .NET Project.
Best wishes,
Ivan Dimitrov
the Telerik team
I thank everyone very much... great community support as always!
I got the control working as it should. However I didn't do it, another developer did (because I don't have VS10/SQL set up yet), so I don't have the actual code files. My question is this: In the tools.xml file (we have in say custom/tools.xml) I would like the button to add an image and also to add a file.
<tool name="DocumentManager" />
<tool name="ImageManager" shortcut="CTRL+G"/>
However, the Image Manager and Document Manager are NOT the managers where you can select from your libraries. They point to the File system. I know what to do in 3.7 but not sure what to tell him for the 4.0 version. (In fact i thought it was opposite in 3.7 where if you didn't want the Library Image dialog you had to change it but it was there by default...)
What is the code to change it and where is it placed?
Thank you!
Hi Laura,
The HtmlField control has a property IsToOverrideDialogs which you can set to false. In this case the control should use the default RadEditor dialogs instead of the custom one that we have implemented.
All the best,
Ivan Dimitrov
the Telerik team
I have a lot of this together, but I'm missing a final piece--I'm not able to put anything into my custom layout control. Could someone tell me what I'm missing?
/resources/testLayoutControl.ascx
<%@ Control Language="C#" %>
<
div
id
=
"layoutWrapper"
runat
=
"server"
class
=
"layoutWrapper"
>
<
div
id
=
"Div1"
runat
=
"server"
class
=
"sf_cols"
>
<
div
id
=
"Div2"
runat
=
"server"
class
=
"sf_colsOut sf_1cols_1_100"
>
<
div
id
=
"Div3"
runat
=
"server"
class
=
"sf_colsIn sf_1cols_1in_100"
>
</
div
>
</
div
>
</
div
>
</
div
>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.Sitefinity.Web.UI;
namespace layouts.resources
public class TestLayoutControl : LayoutControl
public override string Layout
get
return this.CustomTemplate;
public override string AssemblyInfo
get
return GetType().ToString();
set
base.AssemblyInfo = value;
protected override void CreateChildControls()
base.CreateChildControls();
public string CustomTemplate = "layouts.resources.testLayoutControl";
Hi ,
Try to modify the control as shown below
public
class
SampleLayoutControl : LayoutControl
public
override
string
Layout
get
var layout =
this
.ViewState[
"Layout"
]
as
string
;
if
(
string
.IsNullOrEmpty(layout))
layout =
this
.CustomTempalate;
return
layout;
public
override
string
AssemblyInfo
get
return
GetType().ToString();
set
base
.AssemblyInfo = value;
protected
override
void
CreateChildControls()
base
.CreateChildControls();
public
string
CustomTempalate =
"Samples.Layouts.FourBlocksLayoutTemplate.ascx"
;
Nevermind, I just noticed the spelling error: "CustomTempalate". Builds fine now.
I'm making progress here. The "layouts" project builds, and I can place it on the page, but once I place it in the page, I can't place everything in it. Could you take a look and tell me what I'm missing? Also, these are the only two files in the "layouts" project aside from the references; should anything else be there to make this work?
(updated code below)
/Resources/testLayoutControl.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
Telerik.Sitefinity.Web.UI;
namespace
layouts.Resources
public
class
TestLayoutControl : LayoutControl
public
override
string
Layout
get
var layout =
this
.ViewState[
"Layout"
]
as
string
;
if
(
string
.IsNullOrEmpty(layout))
layout =
this
.CustomTemplate;
return
layout;
public
override
string
AssemblyInfo
get
return
GetType().ToString();
set
base
.AssemblyInfo = value;
protected
override
void
CreateChildControls()
base
.CreateChildControls();
public
string
CustomTemplate =
"layouts.Resources.Views.testLayoutControl"
;
<%@ Control Language="C#" %>
<
div
id
=
"layoutWrapper"
runat
=
"server"
class
=
"layoutWrapper"
>
<
div
id
=
"Div1"
runat
=
"server"
class
=
"sf_cols"
>
<
div
id
=
"Div2"
runat
=
"server"
class
=
"sf_colsOut sf_1cols_1_100"
>
<
div
id
=
"Div3"
runat
=
"server"
class
=
"sf_colsIn sf_1cols_1in_100"
>
</
div
>
</
div
>
</
div
>
</
div
>
Going back and forth on this for a while, I'm seeing the best solution is a control with a designer that inherits ContentBlock. I have this all set up, but I'm just trying to tweak the javascript; The content block loads on the designer, but anything I type into it vanishes forever. How can I access this in javascript?
Hi,
If you wrap HtmlFiled it should persist the value automatically. Also you can access the HtmlField properties directly using _htmlEditor
Type.registerNamespace(
"Telerik.Sitefinity.Samples"
);
Telerik.Sitefinity.Samples.ContentBlockCustomDesigner =
function
(element)
// element
this
._htmlEditor =
null
;
Telerik.Sitefinity.Samples.ContentBlockCustomDesigner.initializeBase(
this
, [element]);
Telerik.Sitefinity.Samples.ContentBlockCustomDesigner.prototype =
initialize:
function
()
Telerik.Sitefinity.Samples.ContentBlockCustomDesigner.callBaseMethod(
this
,
'initialize'
);
,
get_htmlEditor:
function
()
return
this
._htmlEditor;
,
set_htmlEditor:
function
(value)
this
._htmlEditor = value;
,
/* --------------------------------- event handlers --------------------------------- */
// Handles the page load event
/* ----------------------------- public methods ----------------------------- */
applyChanges:
function
()
this
.get_propertyEditor().get_control().Html =
this
._htmlEditor.get_value();
,
refreshUI:
function
()
var
html =
this
.get_propertyEditor().get_control().Html;
if
(html)
this
._htmlEditor.set_value(html);
Telerik.Sitefinity.Samples.ContentBlockCustomDesigner.registerClass(
'Telerik.Sitefinity.Samples.ContentBlockCustomDesigner'
, Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);
if
(
typeof
(Sys) !==
'undefined'
) Sys.Application.notifyScriptLoaded();
Thanks Ivan, that worked great!
Would you be able to provide an update to the 2/16/2011 post above for 4.1, which includes the ability to use shared content?
Also, I upgraded to 4.1 this morning, and now the editor window is missing the icons for text formatting. Should this line below have changed to something else?
<
sf:ResourceLinks
id
=
"resourcesLinks"
runat
=
"server"
>
<
sf:ResourceFile
Name
=
"Styles/Window.css"
/>
</
sf:ResourceLinks
>
Hi Connections Academy Developer,
Shared content is implemented in Sitefinity 4.1, Q1 release that is available for downloading.
Can you attach a screenshot represents the second issue( before upgrade and after upgrade)
Kind regards,
Ivan Dimitrov
the Telerik team