locked
Customize Content Editor Web part RRS feed

  • Question

  • I need to create a customized Content Editor web part that will replace the OOTB Content Editor and add my customized web part to the web part list so that I can use it everywhere.

    Does anybody have an idea on how to do that? I can't inherit from the class since the class is sealed.

    BR

    Emmeli

    Wednesday, November 2, 2011 8:17 AM

Answers

  • <Moderator Edit>

    Content below is from http://blog.mastykarz.nl/inconvenient-content-editor-web-part/

    </Moderator Edit>

    Yes Emmeli you right  While in general it wouldn't be particularly difficult to override this behavior, the ContentEditorWebPart is sealed – you cannot extend it nor modify it. While building your own alternative might be an option there is another way to solve this issue using Control Adapters.

    Control Adapters have been introduced in the ASP.NET 2.0 framework as an extra layer of logic which can be used to override the way the presentation layer is being rendered. By benefiting of that concept you can create your control once and reuse it in every project you will ever work on by modifying the presentation layer with Control Adapters.

    Because the ContentEditorWebPart is sealed you cannot extend it. You are still able though, to create a custom Control Adapter which will apply the required modification. In our case it will make all URLs relative.

    The Concept

    The idea of the custom Control Adapter for the Content Editor Web Part is very simple: hookup to the Content Editor Web Part, intercept the HTML rendered by the Web Part, turn all absolute URLs into relative and render the output.

    ContentEditorWebPartAdapter

    public class ContentEditorWebPartAdapter : ControlAdapter
    {
      protected override void Render(System.Web.UI.HtmlTextWriter writer)
      {
        StringBuilder sb = new StringBuilder();
        HtmlTextWriter htw = new HtmlTextWriter(new StringWriter(sb));
        base.Render(htw);
     
        // make all URLs relative
        Regex regex = new Regex(
          "((?:href|src)=\")https?://[^/]+([^\"]+\")");
        string output = regex.Replace(sb.ToString(), "$1$2");
     
        writer.Write(output);
      }
    }

    That's really all. First of all you get the rendered output. It's being stored in the sb StringBuilder. Then you make all absolute URLs relative. While you could use the standard String.Replace to improve the overall performance of this routine, I have chosen for the Regular Expressions to make it a bit more safe and reusable. The last step is writing the output back on the page.

    Linking the ContentEditorWebPartAdapter to the Content Editor Web Part

    The next thing to do is to attach the custom Control Adapter we have just created to the Content Editor Web Part. You do this by creating a .browser (for example Imtech.browsers) file in the App_Browsers directory of your Web Application. This file has to contain the following:

    <browsers>
        <browser refID="Default">
            <controlAdapters>
                <adapter
    controlType="Microsoft.SharePoint.WebPartPages.ContentEditorWebPart"
    adapterType="Imtech.SharePoint.Adapters.ContentEditorWebPartAdapter" />
            </controlAdapters>
        </browser>
    </browsers>
    The controlType attribute defines the type you want to attach to (Content Editor Web Part in our case) and the adapterType defines the full name of our custom Control Adapter. Since I have deployed it to the bin directory, the full type name is sufficient. On the other hand you might want this to make part of your existing assembly residing in GAC. In such case you have to extend the adapterType definition with the fully qualified name including the Public Key Token
    Krishana Kumar http://mosstechnet-kk.com
    • Marked as answer by Emmeli Wednesday, November 16, 2011 8:59 AM
    • Edited by Trevor SewardMVP Tuesday, December 10, 2013 9:37 PM Added source for the content of this post
    Wednesday, November 2, 2011 8:31 AM

All replies

  • What are you trying to achieve with the new CEWP?
    Blog: www.jasperoosterveld.com Twitter: JasITConsultant Please remember to mark your question as answered if this solves your problem.
    Wednesday, November 2, 2011 8:26 AM
  • <Moderator Edit>

    Content below is from http://blog.mastykarz.nl/inconvenient-content-editor-web-part/

    </Moderator Edit>

    Yes Emmeli you right  While in general it wouldn't be particularly difficult to override this behavior, the ContentEditorWebPart is sealed – you cannot extend it nor modify it. While building your own alternative might be an option there is another way to solve this issue using Control Adapters.

    Control Adapters have been introduced in the ASP.NET 2.0 framework as an extra layer of logic which can be used to override the way the presentation layer is being rendered. By benefiting of that concept you can create your control once and reuse it in every project you will ever work on by modifying the presentation layer with Control Adapters.

    Because the ContentEditorWebPart is sealed you cannot extend it. You are still able though, to create a custom Control Adapter which will apply the required modification. In our case it will make all URLs relative.

    The Concept

    The idea of the custom Control Adapter for the Content Editor Web Part is very simple: hookup to the Content Editor Web Part, intercept the HTML rendered by the Web Part, turn all absolute URLs into relative and render the output.

    ContentEditorWebPartAdapter

    public class ContentEditorWebPartAdapter : ControlAdapter
    {
      protected override void Render(System.Web.UI.HtmlTextWriter writer)
      {
        StringBuilder sb = new StringBuilder();
        HtmlTextWriter htw = new HtmlTextWriter(new StringWriter(sb));
        base.Render(htw);
     
        // make all URLs relative
        Regex regex = new Regex(
          "((?:href|src)=\")https?://[^/]+([^\"]+\")");
        string output = regex.Replace(sb.ToString(), "$1$2");
     
        writer.Write(output);
      }
    }

    That's really all. First of all you get the rendered output. It's being stored in the sb StringBuilder. Then you make all absolute URLs relative. While you could use the standard String.Replace to improve the overall performance of this routine, I have chosen for the Regular Expressions to make it a bit more safe and reusable. The last step is writing the output back on the page.

    Linking the ContentEditorWebPartAdapter to the Content Editor Web Part

    The next thing to do is to attach the custom Control Adapter we have just created to the Content Editor Web Part. You do this by creating a .browser (for example Imtech.browsers) file in the App_Browsers directory of your Web Application. This file has to contain the following:

    <browsers>
        <browser refID="Default">
            <controlAdapters>
                <adapter
    controlType="Microsoft.SharePoint.WebPartPages.ContentEditorWebPart"
    adapterType="Imtech.SharePoint.Adapters.ContentEditorWebPartAdapter" />
            </controlAdapters>
        </browser>
    </browsers>
    The controlType attribute defines the type you want to attach to (Content Editor Web Part in our case) and the adapterType defines the full name of our custom Control Adapter. Since I have deployed it to the bin directory, the full type name is sufficient. On the other hand you might want this to make part of your existing assembly residing in GAC. In such case you have to extend the adapterType definition with the fully qualified name including the Public Key Token
    Krishana Kumar http://mosstechnet-kk.com
    • Marked as answer by Emmeli Wednesday, November 16, 2011 8:59 AM
    • Edited by Trevor SewardMVP Tuesday, December 10, 2013 9:37 PM Added source for the content of this post
    Wednesday, November 2, 2011 8:31 AM
  • As Jasper asked what would be the reason for custom content editor webpart - are you after replacing the editing toolbar with some custom toolbar?

     

    -Yogesh Pawar

    Wednesday, November 2, 2011 9:56 AM
  • Hi

    Thanks all for your answer.

    Yes I need to do a custom toolbar, where I need to disable some buttons, for example, "Upload file button" in Insert Tab. This web part must replace the ootb content editor so I can pick it in from the web part list, and add it where ever I want on my site.

    If I understand it right I can disable the buttons with script, and then will the adapter solution work right? I am trying the solution with the adapter right now.

    But would it work if I need to change some properties on the content editor for example if I need to set the "AllowStandardFonts" to not be allowed?

    /Emmeli

    Wednesday, November 2, 2011 10:21 AM
  • Thanks for all your answers, I got it to work with the adapter :).

    I hide my buttons with the OnLoad()

    protected override void OnLoad(EventArgs e)
    {
                                          
                    SPRibbon ribbon = SPRibbon.GetCurrent(this.Page);
                    if (ribbon != null)
                    {
                        //Format tab
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.Bold");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.Italics");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.Underline");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.Strikethrough");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.FontBackgroundColor");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.FontSize");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.Fonts");
                        ribbon.TrimById("Ribbon.EditingTools.CPEditTab.Font.FontColor");

                        //Insert tab
                        ribbon.TrimById("Ribbon.EditingTools.CPInsert.Links.UploadFile");

                             }
                base.OnLoad(e);
      }

    and I used the Render() to set my prefixstylesheet with jquery.

      protected override void Render(System.Web.UI.HtmlTextWriter writer)
      {

                StringBuilder sb = new StringBuilder();
                HtmlTextWriter htw = new HtmlTextWriter(new StringWriter(sb));
                base.Render(htw);
                //http://stackoverflow.com/questions/7615767/how-to-leverage-custom-styles-markup-styles-in-the-sharepoint-2010-cewp-100
               
                // make all URLs relative
                Regex regex = new Regex(
                  "((?:href|src)=\")https?://[^/]+([^\"]+\")");
                string output = regex.Replace(sb.ToString(), "$1$2");
                output = output + "<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js\"></script><script type=\"text/javascript\">ExecuteOrDelayUntilScriptLoaded(function() {  $(\"div[RteRedirect]\").each(function() {var id = $(this).attr(\"RteRedirect\"),editSettings = $(\"#\" + id);if(editSettings.length > 0 && editSettings[0].PrefixStyleSheet != 'al-rtestyle') {editSettings[0]['PrefixStyleSheet'] = 'StyleName';        editSettings[0]['StyleSheet'] = '\u002fStyle Library\u002fen-US\u002fThemable\u002fCore Styles\u002f<somecustomstylesheet>.css'; RTE.Canvas.fixRegion(id, false); } }); }, \"sp.ribbon.js\");</script>";
                writer.Write(output);

       }

    Wednesday, November 16, 2011 9:05 AM
  • KRISHANA, you blatantly copied an article by Waldek Mastykarz. If you copy content please mark your source, or even better just link to the original content.

    Tuesday, December 10, 2013 9:12 PM