Extending Existing Content-Type with Dynamic Fields

Posted by Community Admin on 03-Aug-2018 17:32

Extending Existing Content-Type with Dynamic Fields

All Replies

Posted by Community Admin on 22-Nov-2010 00:00

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.

Posted by Community Admin on 22-Nov-2010 00:00

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

Posted by Community Admin on 23-Nov-2010 00:00

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).

Posted by Community Admin on 23-Nov-2010 00:00

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

Posted by Community Admin on 24-Nov-2010 00:00

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?

Posted by Community Admin on 24-Nov-2010 00:00

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

Posted by Community Admin on 24-Nov-2010 00:00

Thanks much, Ivan.  I appreciate your assistance in this matter.

Posted by Community Admin on 20-Jan-2011 00:00

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

Posted by Community Admin on 20-Jan-2011 00:00

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

Posted by Community Admin on 20-Jan-2011 00:00

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

Posted by Community Admin on 02-Feb-2011 00:00

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

This thread is closed