{"action":"created","issue":{"url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/2363","repository_url":"https://api.github.com/repos/OrchardCMS/OrchardCore","labels_url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/2363/labels{/name}","comments_url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/2363/comments","events_url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/2363/events","html_url":"https://github.com/OrchardCMS/OrchardCore/issues/2363","id":358916982,"node_id":"MDU6SXNzdWUzNTg5MTY5ODI=","number":2363,"title":"Alternates for Dynamic Parts Not Added to Shape Metadata","user":{"login":"aodl","id":14985227,"node_id":"MDQ6VXNlcjE0OTg1MjI3","avatar_url":"https://avatars1.githubusercontent.com/u/14985227?v=4","gravatar_id":"","url":"https://api.github.com/users/aodl","html_url":"https://github.com/aodl","followers_url":"https://api.github.com/users/aodl/followers","following_url":"https://api.github.com/users/aodl/following{/other_user}","gists_url":"https://api.github.com/users/aodl/gists{/gist_id}","starred_url":"https://api.github.com/users/aodl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aodl/subscriptions","organizations_url":"https://api.github.com/users/aodl/orgs","repos_url":"https://api.github.com/users/aodl/repos","events_url":"https://api.github.com/users/aodl/events{/privacy}","received_events_url":"https://api.github.com/users/aodl/received_events","type":"User","site_admin":false},"labels":[{"id":961662386,"node_id":"MDU6TGFiZWw5NjE2NjIzODY=","url":"https://api.github.com/repos/OrchardCMS/OrchardCore/labels/P1","name":"P1","color":"b60205","default":false},{"id":149551459,"node_id":"MDU6TGFiZWwxNDk1NTE0NTk=","url":"https://api.github.com/repos/OrchardCMS/OrchardCore/labels/bug","name":"bug","color":"d93f0b","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/OrchardCMS/OrchardCore/milestones/5","html_url":"https://github.com/OrchardCMS/OrchardCore/milestone/5","labels_url":"https://api.github.com/repos/OrchardCMS/OrchardCore/milestones/5/labels","id":3416760,"node_id":"MDk6TWlsZXN0b25lMzQxNjc2MA==","number":5,"title":"beta3","description":"https://github.com/OrchardCMS/OrchardCore/wiki/Roadmap#beta-3","creator":{"login":"sebastienros","id":1165805,"node_id":"MDQ6VXNlcjExNjU4MDU=","avatar_url":"https://avatars0.githubusercontent.com/u/1165805?v=4","gravatar_id":"","url":"https://api.github.com/users/sebastienros","html_url":"https://github.com/sebastienros","followers_url":"https://api.github.com/users/sebastienros/followers","following_url":"https://api.github.com/users/sebastienros/following{/other_user}","gists_url":"https://api.github.com/users/sebastienros/gists{/gist_id}","starred_url":"https://api.github.com/users/sebastienros/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebastienros/subscriptions","organizations_url":"https://api.github.com/users/sebastienros/orgs","repos_url":"https://api.github.com/users/sebastienros/repos","events_url":"https://api.github.com/users/sebastienros/events{/privacy}","received_events_url":"https://api.github.com/users/sebastienros/received_events","type":"User","site_admin":false},"open_issues":126,"closed_issues":55,"state":"open","created_at":"2018-06-11T19:10:49Z","updated_at":"2018-09-17T17:58:35Z","due_on":"2018-09-03T07:00:00Z","closed_at":null},"comments":1,"created_at":"2018-09-11T07:15:53Z","updated_at":"2018-09-18T06:56:13Z","closed_at":null,"author_association":"NONE","body":"Content [part templates](https://orchardcore.readthedocs.io/en/latest/OrchardCore.Modules/OrchardCore.Templates/README/#content-part-templates) are not available to dynamically defined parts (a dynamically defined part doesn't make use of the `ContentPartDisplayDriver<TPart>`, which is currently responsible for adding the necessary alternates). \r\n\r\nIt would be useful (and less misleading for new comers) if [these templates](https://orchardcore.readthedocs.io/en/latest/OrchardCore.Modules/OrchardCore.Templates/README/#content-part-templates) were available by default for dynamically defined parts as well as strongly typed parts (those with corresponding C# classes).\r\n\r\nDo others agree that this is first a problem? and that it is worth solving?\r\n\r\n### Possible Approach\r\n\r\nThe solution seems to require a default ContentPartDisplayDriver which operates on the basic `ContentPart` object (as opposed to ContentPart subclasses). `ContentItemDisplayCoordinator.BuildDisplayAsync` is responsible for looping through the part drivers that have been registered, and calling every driver's `BuildDisplayAsync` for every part. \r\n```\r\n    foreach (var displayDriver in _partDisplayDrivers)\r\n    {\r\n        try\r\n        {\r\n            var result = await displayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context);\r\n            if (result != null)\r\n            {\r\n                await result.ApplyAsync(context);\r\n            }\r\n       ...\r\n```\r\n\r\nThe part drivers' `BuildDisplayAsync` methods are responsible for checking if they should return early (because the part argument passed in is not of the correct type). i.e. the first few lines look like this \r\n```\r\n    var part = contentPart as TPart;\r\n    if (part == null)\r\n    {\r\n        return Task.FromResult<IDisplayResult>(null);\r\n    }\r\n```\r\n\r\n#### Implementing a Solution\r\n\r\nIf a default ContentPartDisplayDriver would be implemented, inheriting the existing `ContentPartDisplayDriver<TPart>` (where TPart : ContentPart), it could override the BuildDisplayAsync method and perform a more strict type check before returning early (else calling the base implementation) i.e.\r\n```\r\n    if (part.GetType() != typeof(ContentPart))\r\n    {\r\n        return Task.FromResult<IDisplayResult>(null);\r\n    }\r\n```\r\nThis way this default driver would only operate on parts that are not subclasses of ContentPart (indicating that they are dynamically defined in admin UI because they do not have their own ContentPart subclass defined in C#).\r\n\r\nI'm not sure if other changes would be required to support this, and I haven't tried it myself yet. It's just a theory before I shoot off for work.\r\n\r\n\r\ncc @sebastienros, @jtkech (as per our brief discussion on gitter)"},"comment":{"url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/comments/422277015","html_url":"https://github.com/OrchardCMS/OrchardCore/issues/2363#issuecomment-422277015","issue_url":"https://api.github.com/repos/OrchardCMS/OrchardCore/issues/2363","id":422277015,"node_id":"MDEyOklzc3VlQ29tbWVudDQyMjI3NzAxNQ==","user":{"login":"sfmskywalker","id":938393,"node_id":"MDQ6VXNlcjkzODM5Mw==","avatar_url":"https://avatars0.githubusercontent.com/u/938393?v=4","gravatar_id":"","url":"https://api.github.com/users/sfmskywalker","html_url":"https://github.com/sfmskywalker","followers_url":"https://api.github.com/users/sfmskywalker/followers","following_url":"https://api.github.com/users/sfmskywalker/following{/other_user}","gists_url":"https://api.github.com/users/sfmskywalker/gists{/gist_id}","starred_url":"https://api.github.com/users/sfmskywalker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sfmskywalker/subscriptions","organizations_url":"https://api.github.com/users/sfmskywalker/orgs","repos_url":"https://api.github.com/users/sfmskywalker/repos","events_url":"https://api.github.com/users/sfmskywalker/events{/privacy}","received_events_url":"https://api.github.com/users/sfmskywalker/received_events","type":"User","site_admin":false},"created_at":"2018-09-18T06:56:13Z","updated_at":"2018-09-18T06:56:13Z","author_association":"MEMBER","body":"That would be fantastic. Here is some documentation on contributing: http://docs.orchardproject.net/en/latest/Documentation/Contributing-patches/#Branches\r\n\r\nYou already opened an issue, so next step is to fork the repo, do the work and submit a PR."}}
{"actor":{"display_login":"sfmskywalker"}}