<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Extending the Content Editor</title><link>https://community.telligent.com/community/11/w/developer-training/65057/extending-the-content-editor</link><description /><dc:language>en-US</dc:language><generator>14.0.0.586 14</generator><item><title>Extending the Content Editor</title><link>https://community.telligent.com/community/11/w/developer-training/65057/extending-the-content-editor</link><pubDate>Thu, 13 Jun 2019 19:23:43 GMT</pubDate><guid isPermaLink="false">7b716a38-fa5f-4b41-8aeb-66a058a3e7ba</guid><dc:creator>Ben Tiedt</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65057/extending-the-content-editor#comments</comments><description>Current Revision posted to Developer Training by Ben Tiedt on 06/13/2019 19:23:43&lt;br /&gt;
&lt;p&gt;The platform allows developers to extend the content editor to provide for richer content.&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Why_Extend_the_Content_Editor" name="Why_Extend_the_Content_Editor"&gt;&lt;/a&gt;Why Extend the Content Editor?&lt;/h2&gt;
&lt;p&gt;The content editor allows the input of html,&amp;nbsp;images and video, however&amp;nbsp;other types of content cannot be entered or would be difficult to enter for end users. &amp;nbsp;The platform provided extensions to the content editor are good use cases for what extending the content editor can provide.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Source_Code_with_Syntax_Highlighting" name="Source_Code_with_Syntax_Highlighting"&gt;&lt;/a&gt;Source Code with Syntax Highlighting&lt;/h3&gt;
&lt;p&gt;Source code can be entered into the editor without an extension, but without an extension each user is&amp;nbsp;responsible for providing the styling for the source code they enter. &amp;nbsp;By adding a&amp;nbsp;source code extension to the editor, we can simplify the input required by the end user and provide a consistent output for code samples with syntax highlighting.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Polls" name="Polls"&gt;&lt;/a&gt;Polls&lt;/h3&gt;
&lt;p&gt;A Polls extension is also provided with the platform. &amp;nbsp;Without this extension Polls could not be entered using the editor. &amp;nbsp;The Polling extension is able to provide an interface to allow poll entry, rendered those polls and store the data custom set of database tables.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Creating_an_Extension" name="Creating_an_Extension"&gt;&lt;/a&gt;Creating an Extension&lt;/h2&gt;
&lt;p&gt;The platform provides the&amp;nbsp;[[api-documentation:IEmbeddableContentFragmentType Plugin Type|IEmbeddableContentFragmentType]]&amp;nbsp;interface, it can be found in the Telligent.Evolution.Api.Dll. &amp;nbsp;This interface allow new types of content to be entered into the editor.&lt;/p&gt;
&lt;p&gt;This example will create a new EmbeddableContentFragmentType that displays a box inside the content. &amp;nbsp;The background color of the box will be configurable when inserting the content.&lt;/p&gt;
&lt;p&gt;First, we need to provide a unique id (EmbeddedContentFragmentTypeId), name (ContentFragmentName) and description (ContentFragmentDescription) for our content fragment type. &amp;nbsp;We will use the [[api-documentation:ITranslatablePlugin Plugin Type|ITranslatablePlugin]] interface to provide translations for the name and description.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;readonly Guid _fragmentTypeId = new Guid(&amp;quot;6c33babb0c0e45e8b691294b8b6569e5&amp;quot;);

public string ContentFragmentName
{
    get { return _translation.GetLanguageResourceValue(&amp;quot;fragment_name&amp;quot;); }
}

public string ContentFragmentDescription
{
    get { return _translation.GetLanguageResourceValue(&amp;quot;fragment_description&amp;quot;); }
}

public Guid EmbeddedContentFragmentTypeId
{
    get { return _fragmentTypeId; }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We can limit the types the content that can be used when embedding our new content fragment type. &amp;nbsp;In the example we will allow all types, so we will just return true. &amp;nbsp;If we wanted to limit our new type to only be allowed in blog posts, we could return true only when the contentTypeId parameter matches the blog post content type id.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;bool IEmbeddableContentFragmentType.CanEmbed(Guid contentTypeId, int userId)
{
    return true;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The EmbedConfiguration property is used to define the form&amp;nbsp;for entering the data needed to define the embed. &amp;nbsp;In this case, we will allow the user to choose the background color of the embedded box, so we define a single property with the PropertyType of Color.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;PropertyGroup[] IEmbeddableContentFragmentType.EmbedConfiguration
{
    get
    {
        var group = new PropertyGroup(&amp;quot;options&amp;quot;, _translation.GetLanguageResourceValue(&amp;quot;configuration_group&amp;quot;), 1);
        group.Properties.Add(new Property(&amp;quot;color&amp;quot;, _translation.GetLanguageResourceValue(&amp;quot;configuration_color&amp;quot;), PropertyType.Color, 1, &amp;quot;&amp;quot;));
        return new PropertyGroup[] { group };
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The Validate method is provided to verify that the data entered by the end user is&amp;nbsp;correct. &amp;nbsp;A translated error may be returned to the end user to assist in correcting any invalid data.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;EmbeddableContentFragmentValidationState IEmbeddableContentFragmentType.Validate(IEmbeddableContentFragment embeddedFragment)
{
    var color = embeddedFragment.GetString(&amp;quot;color&amp;quot;);

    if (string.IsNullOrEmpty(color))
        return new EmbeddableContentFragmentValidationState(false) { Message = _translation.GetLanguageResourceValue(&amp;quot;configuration_colorinvalid&amp;quot;) };

    return new EmbeddableContentFragmentValidationState(true);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;AddUpdateContentFragments method is called whenever embedded content is added or updated. &amp;nbsp;This can be used to create, update and delete database records for the embeds. &amp;nbsp;This example does not need to use this method, so we will leave it blank.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;void IEmbeddableContentFragmentType.AddUpdateContentFragments(Guid contentId, Guid contentTypeId, IEnumerable&amp;lt;IEmbeddableContentFragment&amp;gt; embeddedFragments)
{

}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The preview image will be displayed as an icon in the editor menu and in the editor to represent the embedded content. &amp;nbsp;For this example, we can just leave this blank and allow the platform to provide an image.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;string IEmbeddableContentFragmentType.PreviewImageUrl
{
    get { return null; }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The Render method is called when the embedded&amp;nbsp;content is being output. &amp;nbsp;A target parameter is also provided, this can be useful if you want to display different output for different targets. &amp;nbsp;The example will read the color parameter we defined in the&amp;nbsp;EmbedConfiguration property. &amp;nbsp;If the color has been set, we will render a div with a fixed height and width and the selected background color.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;string IEmbeddableContentFragmentType.Render(IEmbeddableContentFragment embeddedFragment, string target)
{
    var color = embeddedFragment.GetString(&amp;quot;color&amp;quot;);

    if (String.IsNullOrEmpty(color))
        return String.Empty;

    return String.Format(&amp;quot;&amp;lt;div style=&amp;#39;height: 300px; width: 300px; background-color: {0};&amp;#39;&amp;gt;&amp;#160;&amp;lt;/div&amp;gt;&amp;quot;, color);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here is the completed source code for the Sample&amp;nbsp;IEmbeddableContentFragmentType:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://community.telligent.com/cfs-file/__key/communityserver-wikis-components-files/00-00-00-12-83/SampleEmbeddable_2E00_cs"&gt;community.telligent.com/.../SampleEmbeddable_2E00_cs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once the plugin&amp;nbsp;has been deployed and enabled in the community, when creating a post you will see the option to &amp;quot;Insert Embeddable Box&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;a href="/cfs-file/__key/communityserver-wikis-components-files/00-00-00-12-83/8204.png"&gt;&lt;img src="/resized-image/__size/960x720/__key/communityserver-wikis-components-files/00-00-00-12-83/8204.png" alt=" " /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Select that option and you will be able to configure the background color&lt;/p&gt;
&lt;p&gt;&lt;a href="/cfs-file/__key/communityserver-wikis-components-files/00-00-00-12-83/45706.png"&gt;&lt;img src="/resized-image/__size/960x720/__key/communityserver-wikis-components-files/00-00-00-12-83/45706.png" alt=" " /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After submitting this form, the editor will display the embeddable content using the previewimageurl provided in the code. &amp;nbsp;After creating the post, you should see the box rendered with the chosen background color.&lt;/p&gt;
&lt;p&gt;&lt;a href="/cfs-file/__key/communityserver-wikis-components-files/00-00-00-12-83/6153.png"&gt;&lt;img src="/resized-image/__size/320x240/__key/communityserver-wikis-components-files/00-00-00-12-83/6153.png" alt=" " /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: IEmbeddableContentFragmentType&lt;/div&gt;
</description></item></channel></rss>