Comments (29)
For those of you using Archetype with ModelsBuilder, you might consider trying the "Nested Content" package. It is just as quick and easy to create "custom" datatypes as using Archetype. And since Nested Content uses Doctypes as the "blueprints", and ModelsBuilder uses Doctypes, it's easy to have a model generated for the properties defined on a Nested Content automatically.
An example scenario:
The Doctype "Homepage" has a NestedContent of type "ResourceBox" (which has some properties: Title, Description, Link, Image, etc.)
By default, ModelsBuilder will create a model for ResourceBox, since it is defined as a DocType, and just like for other Doctypes, we can create a custom partial to add or change the way properties are returned.
The "HompageResourceBoxes" property on the "Homepage" model is generated automatically as:
/// <summary>Resource Boxes</summary>
[ImplementPropertyType("HomepageResourceBoxes")]
public object HomepageResourceBoxes
{
get { return this.GetPropertyValue("HomepageResourceBoxes"); }
}
So, we override that with a custom property implementation:
/// <summary>Resource Boxes</summary>
[ImplementPropertyType("HomepageResourceBoxes")]
public IEnumerable<ResourceBox> HomepageResourceBoxes
{
get
{
var items = this.GetPropertyValue<IEnumerable<IPublishedContent>>("HomepageResourceBoxes");
return items.ToResourceBoxes();
}
}
...
public static IEnumerable<ResourceBox> ToResourceBoxes(this IEnumerable<IPublishedContent> Content)
{
var list = new List<ResourceBox>();
foreach (var item in Content)
{
var rb = new ResourceBox(item);
list.Add(rb);
}
return list;
}
Now you can access these strongly-typed in a view like:
@if (Model.Content.HomepageResourceBoxes.Any())
{
foreach (var box in Model.Content.HomepageResourceBoxes)
{
<div class="resourceitem">
<p><a href="@box.Link.Url">@box.ResourceBoxTitle</a></p>
@Html.Raw(box.Description)
</div>
}
}
Just an alternative to consider.
from modelsbuilder.original.
I do understand the need but I fail to see how I could generate that Archetype-specific code... not mentionning that every custom datatype will then want me to generate specific code... so I'd end up generating models for custom datatypes...
Where should I get the Slider class definition from? That's Archetype-specific.
That being said... we can discuss how to add some extension points in the ModelsBuilder so that datatypes can provide their own models. When hitting a property type, we would want to check if there's a custom builder for the corresponding datatype, and use it to get
- the returned CLR type (here, IEnumerable)
- the property getter code
- extra code (here, the Slider class)
And then it would be up to Archetype to figure out how to implement the extension point.
So we maintain separation, modularity, etc.
Making sense? Suggestions?
from modelsbuilder.original.
Jumping in on this, just to throw an idea out there.
Would it be possible in the ModelsBuilder to access the PropertyValueConverter
for a given property-editor? If so, then the PropertyValueType
attribute could be used to get the object type?
See Archetype's ArchetypeValueConverter
class.
I can't comment on @jbreuer's Slider
code - that's project specific. In those cases I would use a custom TypeConverter
(as .GetPropertyValue<T>
would pass the ArchetypeModel
to it).
from modelsbuilder.original.
I like the idea of the ModelsBuilder to have an extension point so that datatypes can provide their own model.
In that case Archetype could use that extension point and return the correct model and have it go through it's own converter. The ModelsBuilder would than generate something like this for the Archetype Slider datatype.
[ImplementPropertyType("slider")]
public Slider Slider
{
get { return this.GetPropertyValue<Slider>("slider"); }
}
from modelsbuilder.original.
@zpqrtbnk Agreed. I wouldn't code data type specific code, but the ability to add extension points seems very useful.
from modelsbuilder.original.
Would those extension points be part of the ModelsBuilder or part of the Umbraco core? If they are part of the ModelsBuilder it would mean that Archetype probably needs a reference to the ModelsBuilder unless you use reflection.
from modelsbuilder.original.
I'd keep them separate and maybe propose implementing an interface that ModelsBuilder exposes and use reflection to grab any implementations in memory.
That way Archetype doesn't need to know about ModelsBuilders, ModelsBuilders doesn't need to know about Archetype and a third bit of code marries the two.
from modelsbuilder.original.
@leekelleher - the ModelsBuilder already accesses the property's PropertyValueConverter to get the CLR type returned by the property, as indicated by the PropertyValueType attribute, or by the GetPropertyValueType() method of the IPropertyValueConverterMeta, if implemented.
So if the Archetype property value converter can tell us what exact CLR type it would return for a given property, we would use it in ModelsBuilder. Ideally in @jbreuer situation, Archetype converter would indicate that it converts to IEnumerable<Slider>
and we would generate the following code:
[ImplementPropertyType("slider")]
public IEnumerable<Slider> Slider
{
get
{
return = this.GetPropertyValue<IEnumerable<Slider>>("slider");
}
}
That way, ModelsBuilder, Umbraco and Archetype are completely independent. But it means that Archetype has to be able to implement the proper converter, that the converter has a way to figure out the specific CLR type it returns, and that the Slider
class has to be generated somehow, somewhere.
Thinking of it, I think that's the cleanest way to do it.
from modelsbuilder.original.
This is more related to Archetype than the models builder, but it's related to this topic. When there is some way to generate models for Archetype it might be good to also think about nested Archetypes. So you first need to generate models for the Archetype datatypes that don't have any nested Archetypes and than for the ones that do. That way the Archetype model can also have another nested Archetype model as an IEnumerable property.
from modelsbuilder.original.
Now that the grid editor for Umbraco 7.2 is getting closer it might be nice to kick this topic again. It would be cool if you could also generate models for the grid editor :-).
from modelsbuilder.original.
+1 for "also generate models for the grid editor" :-)
from modelsbuilder.original.
I was just looking at the Grid Layout myself and hoping the model builder would work with it.
I'm guessing it may be some time off.
from modelsbuilder.original.
+1 Grid editor in u7.2
from modelsbuilder.original.
Regarding the Grid... I found that the 'Skybrud.Umbraco.GridData' library works well.
It really isn't very much work to override those Grid properties in the customized partial class:
using Skybrud.Umbraco.GridData;
using Umbraco.Web;
using Zbu.ModelsBuilder;
/// <summary>
/// The text page.
/// </summary>
public partial class TextPage
{
/// <summary>
/// Gets the page body text as a grid object
/// </summary>
[ImplementPropertyType("PageBodyText")]
public GridDataModel PageBodyText
{
get
{
return this.GetPropertyValue<GridDataModel>("PageBodyText");
}
}
}
from modelsbuilder.original.
Hey Folks,
I know this is an old post, but I noticed some nice changes in the Ditto develop branch which make implementing POCO Archetypes, or whatever really for that matter, quite easy. I created a quick repo (https://github.com/micklaw/Ditto.Resolvers) PoC today which shows using POCOs for Archetypes and Nested Archetypes via Ditto.
This does currently only hang from the develop branch of Ditto, so is not practical for use just now, but hopefully when or if those changes are merged in it should start working or be a good started for implementation.
Cheers
from modelsbuilder.original.
I'm late to the Ditto party, but will be testing the main package soon so I can formulate an intelligent response to this :)
from modelsbuilder.original.
Planning to discuss the whole modeling thing with co-modelers at CG15!
from modelsbuilder.original.
I'll stay tuned :)
from modelsbuilder.original.
@micklaw Thanks for posting that repo for making Ditto and Archetype work together. However it's not clear to me what your code does. Meaning if I just create a POCO like so:
using Archetype.Models;
using Umbraco.Core.Models.PublishedContent;
namespace MendozaApp.UmbracoExtensions.Wiki.Models
{
public class WikiTopicModel : PublishedContentModel
{
public WikiTopicModel(Umbraco.Core.Models.IPublishedContent content) : base(content) { }
public string Content { get; set; }
public ArchetypeModel QuickLinks { get; set; }
}
}
I'm then able to access the model on the template like the following without using any additional code:
var pageModel = Model.Content.As<WikiTopicModel>();
@foreach (var x in pageModel.QuickLinks)
{
<div>@x.GetValue("someProperty")</div>
}
Does your code map the Archetype properties as well to a model?
Sorry for the questions.
from modelsbuilder.original.
Don't be sorry, I haven't exactly written pages of docs =)
Yeah, that's the idea. There's a brief explanation on the read me on the GitHub page. Basically there will be a POCO for your DocType (Ditto) and also a POCO for your Archetype.
To bind an Archetype on your DocType class you will create a public property and decorate that with an Attribute:
[ArchetypeResolver("DifferentPropertyName")]
public List List { get; set; }
CustomArchetype in this instance would be your Archetype POCO and its fields would map to the properties you have created in your Archetype. As long as CustomArchetype inherits from ArchetypeFieldsetModel and it has the same name as the fieldset alias in the datatype it should just work.
I'll knock up an example when the kids are asleep. Couldn't do it one handed ;)
from modelsbuilder.original.
Ok sounds good. Not sure if @zpqrtbnk wants this thread to continue on his project, but thanks for looking into this.
from modelsbuilder.original.
@kgiszewski I've added a sample project to the solution to show how this works, hopefully it gives the gist. I think your right, this chat should probably be moved to the new repository so were not spamming. Anything else you want to know just add as a Issue on https://github.com/micklaw/Ditto.Resolvers and i'll get back to you asap. I'll also get cracking on some docs.
from modelsbuilder.original.
@kgiszewski I'm happy having this thread here ;-) But if you think of a more appropriate place, just move it there and post the link here. It's a cross-solutions discussion anyway.
Highly interesting to me though, because:
- Models generation and caching. With the (currently experimental) NuCache, the actual IPublishedContent objects will be cached (and not recreated from Xml all the time). And if the models factory is used, it's the model itself that is cached. Brings flexibility and performance, but requires a clarification of what can be done, and what cannot, with models.
- Nested/Detached/Virtual/YouNameIt content. At the moment Core is focused on IPublishedContent -- our own, those that we manage, those that are nodes in the database and have an ID, etc. But with Archetype, the Grid, and other projects, it becomes obvious that solutions should exist for a somewhat unified way of dealing with content, whether it's a "true node" or only a "part" of a true node.
from modelsbuilder.original.
Hi guys, on the subject of Archetype & Models Builder working nicely together, I have put together a little add-on that takes care of it on data type save. It will create a strongly typed model (cs file) based off of the Archetype prevalues. It also overrides the ArchetypeValueConverter so Archetype can tell the Models Binder what Type to expect. https://github.com/LoganPeck/Umbraco-Archetype-Model-Binder-Add-On
This is my first time contributing code anywhere so my documentation/coding style may be off. Feel free to check it out and let me know if there are any suggestions or questions. Also feel free to contribute as well!
from modelsbuilder.original.
Thanks for the advice. I've also switched to Nested Content and it works really great! https://gist.github.com/jbreuer/0a5996e5e6bf881ce847
from modelsbuilder.original.
Quick comment: I don't think the ModelsBuilder will be able to "generate" models for Archetype anytime soon. The good thing with packages such as NestedContent is that they rely on the already-existing content type system, and therefore can have models easily generated.
Next step is to add a way so that we can easily figure out the model type that would be returned by a nested content property. Which, I think, is feasible. There might be a way to generate the IEnumerable<ResourceBox>
above directly. Work-in-progress...
from modelsbuilder.original.
That would be great, Stephan! I don't use so many NC properties that the customizing work is too much for me, but those who do use them heavily would certainly benefit from a helping hand :-)
from modelsbuilder.original.
please add this feature....
from modelsbuilder.original.
Been a long time - closing.
from modelsbuilder.original.
Related Issues (20)
- Generating models using the VS extension can cause namespace issues HOT 3
- Cleaner csproj include generated files HOT 1
- Can't Rebuild Models After Deleting Document Type HOT 6
- Interface definition only generated when document type is in use HOT 1
- Request error: The URL returned a 404 (not found): /App_Plugins/ModelsBuilder/modelsbuilder.html HOT 1
- Provide option for generated code to use Language Fallback HOT 7
- ModelsBuilder API Generates first IPublishedElement then never finishes HOT 10
- VS Extension: Method not found: 'System.String Umbraco.ModelsBuilder.Building.Compiler.CreateValidIdentifier(System.String)' HOT 2
- v4: Repository shouldnt link to local nuget server
- v4: If Document type with Template is created Umbraco fails with save of Document Type
- Implemented property keeps being generated HOT 6
- ModelsBuilder on Umbraco v8.8 HOT 10
- v4: Generator should be swappable / extendable
- Generated Models missing PublishedElementModel on generated model.
- Stack Overflow when implementing same interface in generated and partial class
- VS Extension install issue
- Execute ModelsBuilder Programmatically
- When generating models for IPublishedElement it adds a controller no matter what
- UmbracoModelsBuilder: UmbracoModelsBuilder failed to generate code: NullReferenceException HOT 1
- VS2022 HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from modelsbuilder.original.