Custom form - HTML field types including <head> tags

Topics: Visual editor
Aug 19, 2011 at 12:35 AM

Hi,

We have defined some custom forms to edit data from external databases using the IData interface and xml files to set the field editors. Some of the fields contain HTML, so we link them to the InlineXhtmlEditor contol. E.g.:

      <InlineXhtmlEditor Label="Description" Help="This is a description of the glossary topic.">
        <InlineXhtmlEditor.Xhtml>
          <cms:bind source="Description" />
        </InlineXhtmlEditor.Xhtml>
      </InlineXhtmlEditor>

 

The problem we are having is that the HTML editor always includes HTML and HEAD tags in the markup. The content of the fields are being added in existing pages, so these tags are invalid. Is there any way to change the editor to only provide "raw" html and not an entire document?

Thanks,

Larry

Coordinator
Aug 19, 2011 at 1:48 AM

The xhtml visual editor is only able to emit complete well formed xhtml documents, but you could perhaps attach to OnBeforeAdd and OnBeforeUpdate data events for your IData types and examine fields, removing unwanted html and head elements. See http://api.composite.net/html/T_Composite_Data_DataEvents_1.htm

> The content of the fields are being added in existing pages, so these tags are invalid.

When you say 'existing pages' do you mean pages Composite C1 renders? If so, we *should* allow any number of complete xhtml documents in outputs from layouts, page contents and functions - when a Composite C1 page is rendered all xhtml documents that are 'nested' inside other xhtml documents simply get 'pulled up/normalized', so the root xhtml document ends up being valid (and all elements in nested head's gets added to the root xhtml head). This should "just work" and you should never get a <html xmlns="(xhtml ns here)"> tag nested inside your page markup.

If you do get html, head and body tags inside your root page body tag, and Composite C1 render the page, please send a sample html snippet showing bad output, C1 version info and what templating tech you use. In this case we should just fix the bug you experience, not try to "make the data fit the bug".

Aug 19, 2011 at 1:58 AM

Hi,

Thanks again for the quick response!

The reason the head and body tags are coming through on the pages is because we have custom asp.net user controls that render repeater controls, such as the ListView, inside a composite page. These custom controls add the html from the database fields to the page. We use the "LoadUserControl" method on the composite page, which then outputs a data repeater.

So probably there is nothing that Composite can do about this...

Cheers,

Larry

Aug 19, 2011 at 7:46 AM
Edited Aug 19, 2011 at 7:51 AM

Hi, you should look at the Contrib project which is able to do exactly this. Either by using the CompositeC1Contrib.Web.UI.Renders.C1MarkupControl directly or using the PageRendererHelper class. It used to contain some references to internal and private methods to the C1 core since its API was not very forthcoming on this point. It has gone better, but this helper-class still contains many hours of reverse-engineering to make it work :)

An example for rendering and executing all C1 functions from a content placeholder can look like this

using Composite.Core.WebClient.Renderings.Page;

using (var data = new DataConnection())
            {
                PageRenderer.CurrentPage = data.Get<IPage>().Single(p => p.Id == pageId);

                var content = DataFacade.GetData<IPagePlaceholderContent>().Single(p => p.PageId == pageId);

                var helper = new PageRendererHelper();
                var mapper = (IXElementToControlMapper)helper.FunctionContext.XEmbedableMapper;
                var doc = helper.RenderDocument(content);
                var body = PageRendererHelper.GetDocumentPart(doc, "body");

                addNodesAsControls(body.Nodes(), plc, mapper);

                if (Page.Header != null)
                {
                    var head = PageRendererHelper.GetDocumentPart(doc, "head");
                    if (head != null)
                    {
                        addNodesAsControls(head.Nodes(), Page.Header, mapper);
                    }
                }
            }

private static void addNodesAsControls(IEnumerable<XNode> nodes, Control parent, IXElementToControlMapper mapper)
    {
        foreach (var node in nodes)
        {
            var c = node.AsAspNetControl(mapper);
            parent.Controls.Add(c);
        }
    }
Aug 21, 2011 at 11:35 AM

Thanks for the info...

 

Larry