1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Extending Existing Content-Type with Dynamic Fields

Extending Existing Content-Type with Dynamic Fields

11 posts, 1 answered
  1. Bob Evans
    Bob Evans avatar
    19 posts
    Registered:
    22 Jun 2012
    22 Nov 2010
    Link to this post

    Does the Sitefinity 4 RC allow extending the existing content-types with dynamic fields (previously titled metafields)?  I'm attempting to add a new text field to the 'Blog Posts' content-type, but although I was able to create a new dynamic field (using the fluent-API) I have been unsuccessful in customizing the Sitefinity back-end to save any values for it.

     

    Starting from the top, my initial attempt to create a new field was through the Sitefinity 4 administration by:

     

    1. Selecting Administration > Settings > Advanced.

    2. Expanded Blogs > Postsbackend > Views > Blogsbackendpostedit > Sections

    3. Create a new Section titled 'NoteSection'

    4. Expanded NoteSection > Fields

    5. Create a new field resulted in error 'Cannot create instance of ... because it is an abstract class.'  Please see the attached screen capture for more details.

     

    After a little reading through the documentation it doesn't state whether any of the administration for this is completed (yet), so instead I followed some of the available fluent-API examples to create append a new 'notes' field to the BlogPost content-type:

    App.WorkWith()
        .DynamicData()
        .Type(typeof(BlogPost))
        .Field()
            .CreateNew("Note", typeof(string))
                .Do(f =>
                    {
                        f.FieldName = "note";
                        f.ColumnName = "note";
                        f.Title = "Note";
                        f.DBSqlType = "NVARCHAR(MAX)";
                        f.DBType = "LONGVARCHAR";
                    })
                .Done()
        .SaveChanges(true);

    This worked successfully and I can see a new column titled 'note' within the underlying table.  Now the intention was to hook this field up to the existing administrative screen for editing Blog Posts.  Since creating new fields through the UI is currently broken I got around this I edited an existing field (the Title field) by changing its name and saving, then un-doing my changes.  The result was that I was able to see that the following XML file ‘/App_Data/Sitefinity/Configuration/BlogsConfig.xml’ saved those field customizations.  Following suite I replicated the field-definition in the XML file to reference the ‘note’ dynamic field I had created:

    <?xml version="1.0" encoding="utf-8"?>
    <blogsConfig xmlns:config="urn:telerik:sitefinity:configuration" xmlns:type="urn:telerik:sitefinity:configuration:type" config:version="4.0.907.0">
        <providers>
            <add version="4.0.907.0" name="OpenAccessDataProvider" />
        </providers>
        <contentViewControls>
            <contentViewControl definitionName="PostsBackend">
                <views>
                    <view viewName="BlogsBackendEditPost" type:this="Telerik.Sitefinity.Web.UI.ContentUI.Views.Backend.Master.Config.DetailFormViewElement, Telerik.Sitefinity, Version=4.0.907.0, Culture=neutral, PublicKeyToken=b28c218413bdf563">
                        <sections>
                            <sections name="NoteSection">
                                <fields>
                                    <field HideIfValue="" description="" example="" fieldType="Telerik.Sitefinity.Web.UI.Fields.TextField" type:fieldType="System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" fieldVirtualPath="" fieldName="Title" type:this="Telerik.Sitefinity.Web.UI.Fields.Config.TextFieldDefinitionElement, Telerik.Sitefinity, Version=4.0.907.0, Culture=neutral, PublicKeyToken=b28c218413bdf563" />
                                    <field rows="4" HideIfValue="" id="noteField" dataFieldName="Note" wrapperTag="Li" title="" description="" example="" fieldType="Telerik.Sitefinity.Web.UI.Fields.TextField" type:fieldType="System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" fieldVirtualPath="" resourceClassId="" cssClass="" fieldName="Note" type:this="Telerik.Sitefinity.Web.UI.Fields.Config.TextFieldDefinitionElement, Telerik.Sitefinity, Version=4.0.907.0, Culture=neutral, PublicKeyToken=b28c218413bdf563">
                                        <expandableDefinition expandText="" expanded="True" />
                                        <validator expectedFormat="None" maxLength="-1" minLength="-1" regularExpression="" required="False" validateIfInvisible="True" />
                                    </field>
                                </fields>
                            </sections>
                        </sections>
                    </view>
                </views>
            </contentViewControl>
        </contentViewControls>
    </blogsConfig>

    Saving this file and refreshing the administrative interface shows that my new ‘note’ field showing beneath the NoteSection section.  Furthermore, when editing a blog post through the back-end I was able to see that a new section and form-field were added allowing the user to enter content for the ‘note’, which was great progress.

    However, the value is never saved!  Whatever content I type in the ‘note’ input field when I choose to save the screen is refreshed and the content is removed.  Attaching SQL Server Profile and observing the SQL statements transmitted confirms my suspicion that although the dynamic field was added to the table and attached to the back-end view it is not being persisted by the ORM.

    It may be the case that I’m going about this in a completely incorrect manner.  So my question is: Has anyone been successful in customizing content-types with new dynamic fields?  If so, how did you do it?

    Any assistance would be much appreciated.

  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    22 Nov 2010
    Link to this post
    Hello Bob,

    I suggest that you should check this post - Creating Dynamic Type

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Bob Evans
    Bob Evans avatar
    19 posts
    Registered:
    22 Jun 2012
    23 Nov 2010
    Link to this post
    Thanks Ivan -- In that thread there's quite an in-depth discussion on how to implement a new content-type and hook it into the Sitefinity back-end.  However, what I'm trying to accomplish shouldn't require this level of detail.  All I want to do is add a new dynamic field (in former 3.x terminology 'metafield') to an existing out-of-the-box Sitefinity module and have it show in the existing admin section (in this case, the Blogs module).

    In Sitefinity 3.x we had the ability to edit the web.config and add a new metafield definition to the <metafields> region, and then customize the administrative control definition (located at \Sitefinity\Admin\ControlTemplates\<Module>\<TypeNameMode>Item.ascx) to add a new control whose ID corresponded to the metafield's ID.  Sitefinity would then manage the persistence of the field value when creating/updating items of that content type using the administrative back-end.

    How can we do the same in Sitefinity 4?  The documentation and code samples show how to use the Fluent API to create/update/delete dynamic fields, but there is no explanation on how to 'hook-up' the back-end so that Sitefinity will manage them through its existing interface(s).
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    23 Nov 2010
    Link to this post
    Hello Bob,

    1.Currently dynamic dynamic fields and custom dynamic types can be created only programmatically. We will provide UI for custom fields in Modules and Pages for the official release. This will allow you to create your fields directly from the UI with several clicks.

    Programmatically you have to create a new field for a given type

    public void TryCreateDinamicField()
     {
       //create
       App.WorkWith().DynamicData().Type(typeof(NewsItem)).Field().TryCreateNew("WriterName", typeof(string)).SaveChanges(true);
      //get
       var dinamicContent = App.WorkWith().DynamicData().Fields().Where(dc => dc.FieldName == "WriterName").Get();
          
     }


    2. You have to add a FieldControl in the definition of the module you want to modify. DataFieldName should be the same as the name of your custom metafield. This should ensure that the data will be persisted by the ContentService web service and its methods.

    sample

    var titleField = new TextFieldDefinitionElement(mainSection.Fields)
               {
                   ID = "titleFieldControl",
                   DataFieldName = "Title",
                   DisplayMode = displayMode,
                   Title = Res.Get<NewsResources>().lTitle,
                   CssClass = "sfTitleField",
                   ResourceClassId = typeof(ModuleResources).Name,
                   WrapperTag = HtmlTextWriterTag.Li,
               };


    You could also check our SDK with a sample module.

    Sincerely yours,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. Bob Evans
    Bob Evans avatar
    19 posts
    Registered:
    22 Jun 2012
    24 Nov 2010
    Link to this post
    Great, this makes sense.  The end result is that I should see the \App_Data\Sitefinity\Configuration\BlogsConfig.config modified to include the appropriate XML-block(s) that represent my new dynamic field?  Because after running my code against my Sitefinity 4 RC instance I don’t see any noticeable effect.  The .config file is not updated nor do I see any changes within the Sitefinity administrative UI.

    I added a new dynamic field via the Fluent API as follows (this works, I can see the underlying database table has been modified to include the new column):

    App.WorkWith()
        .DynamicData()
        .Type(typeof(BlogPost))
        .Field()
            .CreateNew("Note", typeof(string))
                .Do(f =>
                    {
                        f.FieldName = "note";
                        f.ColumnName = "note";
                        f.Title = "Note";
                        f.DBSqlType = "NVARCHAR(MAX)";
                        f.DBType = "LONGVARCHAR";
                    })
                .Done()
        .SaveChanges(true);

    Then I ran the following code-block to update the Blogs configuration – This should have added a new Section titled ‘Notes’ with a single field titled ‘Note’:

    BlogsConfig blogsConfig = new BlogsConfig();
     
    ContentViewControlElement postsBackEnd = blogsConfig.ContentViewControls["Postsbackend"];
    ContentViewDefinitionElement blogsBackendEditPostDefinition = postsBackEnd.ViewsConfig["BlogsBackendEditPost"];
     
    DetailFormViewElement detailView = (DetailFormViewElement)blogsBackendEditPostDefinition;
     
    ContentViewSectionElement noteSection = new ContentViewSectionElement(detailView.Sections);
     
    TextFieldDefinitionElement noteField = new TextFieldDefinitionElement(noteSection.Fields)
        {
            ID = "noteFieldControl",
            DataFieldName = "note",
            DisplayMode = FieldDisplayMode.Write,
            Title = "Note",
            CssClass = "sfTitleField",
            WrapperTag = HtmlTextWriterTag.Li,
            ResourceClassId = typeof(BlogResources).Name,
        };
     
    noteSection.Fields.Add((FieldDefinitionElement)noteField);

    But in the end the code runs successfully and nothing is performed (neither the Section nor the Field are created).

    Am I doing something incorrect?  Do I need to run some instance method to have the changes persist themselves?
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    24 Nov 2010
    Link to this post
    Hi Bob,

    The first code is fine. It has added a new field to your BlogPost type. The second code should be added in a custom definition class as shown in Creating Dynamic Type class. Currently it is not possible to change the definition for a given view. For the official release we will have out of the box functionality that will allow you to do this from the UI - adding dynami fields and replacing definitions. Currently you can show the persisted data of your custom field in with a custom control, but it is hard to add the new field in an existing view because of the missing implementation for this in the RC.

    Sincerely yours,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
    Answered
  7. Bob Evans
    Bob Evans avatar
    19 posts
    Registered:
    22 Jun 2012
    24 Nov 2010
    Link to this post
    Thanks much, Ivan.  I appreciate your assistance in this matter.
  8. Tony Bolton
    Tony Bolton avatar
    33 posts
    Registered:
    06 Oct 2009
    20 Jan 2011
    Link to this post
    Hi Ivan,

    Apologies I keep posting to these old threads, but they're relevant so don't want to duplicate matters!

    It says above that the UI will allow you to create dynamic fields in the official release.  I'm using the official release, but I'm still getting the same problem as Bob ie. "Cannot create an instance of Telerik.Sitefinity.Web.UI.Fields.Config.FieldDefinitionElement because it is an abstract class."

    This partly was me trying to create a 'meta' field against the News object so I could then use the image selector as the editor type, but I can't add a new field to try this out.

    Is this something that's already known about and planned for rectification?

    Cheers,
    Tony
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    20 Jan 2011
    Link to this post
    Hi Tony,

    You can create a custom fields in the official release of Sitefinity 4.0.

    Greetings,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  10. Tony Bolton
    Tony Bolton avatar
    33 posts
    Registered:
    06 Oct 2009
    20 Jan 2011
    Link to this post
    Hi Ivan,

    Thanks for the vid - I was aware of the custom fields.  I guess what I'm stuck how to access these programmatically - is there a help page for that somewhere, as previously I'd use the GetMetaField() method?

    Thanks again,
    Tony
  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    02 Feb 2011
    Link to this post
    Hello Tony ,

    To set or get a value you can use SetValue and GetValue extensions.

    You should have a reference to Telerik.Sitefinity.Model

    Name:

    Telerik.Sitefinity.Model.DataExtensions

    Assembly:

    Telerik.Sitefinity.Model



    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
11 posts, 1 answered