Architectural questions for building a system on top of Umbraco, using Razor
Hello,
I would like to build a platform with various tools and add-ons on top of
Umbraco. The vision is that I would have Umbraco installed at various
locations, who could in turn install various plug-ins and packages that would provide
additional functionality while leveraging the benefits of Umbraco such as the
CMS, security, blogging, and other features. Each of the plug-ins/ packages
I would provide would pull their data from a back end system that I would
support.I am planning on creating a set
of WCF Services for each of these plug-ins which would allow for saving and
retrieval to the back end system.
I would like to create these plug-ins/packages using Umbraco 6 to take
advantage of the MVC Razor support. My thought is that if I use Razor, an
administrator might be able to change the cshtml files to fit custom scenarios
without impacting future builds, customizing the view for a particular need
(i.e. in one instance a control may need to be rendered as a table, in another
it may need to be rendered as a set of div tags, etc).
I am, however, running into a bit of a stumbling block on deciding how to
architect everything.
For the purpose of this example, I would like to work on creating a
plug-in/package that would be a simplified News service (I know, there is
already a News package in Umbraco, but I need a simple example).I would need to have three or four controls.
1.News Player – A control that is able to show 4-5 news
items, and cycle through them using a pager.
2.News Grid – A grid that shows all of the News Items,
with the ability to page through past News Items and sort the Grid.
3.News Administration – A control that allows an
Administrator to enter new News Items, delete old News Items, etc.
4.Configuration – A control for the Umbraco Backoffice
which will allow me to set up the WCF configuration in the web.config to talk
to the back-end system.
I believe I will create the Configuration Control using a traditional
ASP.NET User Control for ease of use and simplicity.Everything else, I figure I will create via MVC
and Razor scripting.
I would like to be able to pass parameters into the News Player and News
Grid controls.These would be for things
like, when rendering the News Player providing a link to where in the site the
News Grid is located.This way the News
Player can have a link to the News Grid, and when the user is viewing the
player, they can click a link to get to the Grid.In addition, the News Grid and News Player
should be passed a parameter on where the Administration page is located, so if
the user has rights to view the Administration page they will have an option to
click a link to get there.In my mind,
these controls will need to be Macros so we can pass a ContentPicker parameter,
and the view would then use Umbraco’s code base to create a link to the other
node, check security, etc.
As I have been working on this, I am stuck at a cross roads at how to
architect this.
From what I understand, I can create my Surface Controllers one of two ways.
1.Standard Surface Controller
If I create this as a standard Surface Controller,
I would create the DLL, install it in the Bin folder, and create all of the
Views (cshtml) via Umbraco’s interface.It would allow me to have the Views be somewhere that an Administrator
could alter them.This way if they
needed to change the grid from a table layout to a div layout, it could be
done.
I have tested, this, and it seems to work.I have the following code:
Controller:
publicclassNewsSurfaceController : SurfaceController{publicActionResult Index(){return Content("hello world");}[ChildActionOnly]publicActionResult NewsPlayer(){return PartialView("NewsPlayer", new Models.NewsItem(0, "Hello from NEAT News"));}}
Model:
public class NewsItem { #region Constructor public NewsItem(int newsItemID, string title) { this.NewsItemID = newsItemID; this.Title = title; } #endregion #region Public Properties public int NewsItemID { get; set; } public string Title { get; set; } #endregion }
View (under Partial View Macro Files):
@inherits Umbraco.Web.Mvc.UmbracoViewPage<Centeva.GovAP.Plugins.News.Controls.Umbraco.Models.NewsItem> The name specified is here: <br /> <strong>@Model.Title</strong>
I believe it doesn’t like the Model that was passed
in, it is as if it is by-passing the controller.
2.Plug-in Surface Controller
The other way to do this is to create a Plug-In
Surface Controller.To do this, I simply
add an attribute to the controller:
[PluginController("GovAP")]
Next I place the views in the appropriate area of
the Umbraco site:
App_Plugin/<Area>/Views/<Controller>
The View seems much the same.
When calling the code from the Template, it would
look something like this:
@Html.Action("NewsPlayer", "NewsSurface", new {area = "GovAP" })
This works fine.
The problem I see is that if I use the Plug-in approach, I don’t see an easy
way to pass in variables via Macros.I
would like the user experience from Umbraco’s back office to be able to add a
component, and simply have it pull up a drop down of all of the nodes in the
site and select the node that has the Admin features for the control, or the
Grid version of the control, etc.With
the Plug-in, I can’t see the ability to do this.
With the non-plugin approach, you can create a Package of all of the macro’s,
scripts, etc.That is great.However, it seems that I am unable to
actually create a macro, use the macro, or use parameters passed in with the
Macro, with the view I create. Is this because I can not use a Custom Model
with Macro’s?What is the best way to
set this up so an Administrator can use Umbraco to easily fill out these
Parameters?
If I want the ability for the Admin to modify the views, am I best using
Partial View Macro Files?Would I be
better off using a Plugin?
If I use Partial View Macro Files, can I use a Custom
Model?If not, what is the best way to
gain access to my back end models?Do I
just make a call to my BLL using Razor, and access it that way?If using a Custom Model, can I some how
access Macro Parameters?How is this
best done?
If I am creating a package, is there any way I can privately
deploy that package to my webserver, and have Umbraco check that server for an
updated version?
Thank you for the response. It wasn't quite what I was looking for, in that I was hoping to have it be a Macro so that I could take advantage of Macro Properties in Umbraco, and allow the Administrators to interface with the views using a simple and powerful Gui. For example, if I would like the Node ID of a different page passed into the View, I would like the use to do this via the Macro's properties, where there is a simple drop down for them, rather than having to know the Node ID and pass it in through the function call. Thank you for the suggestion though.
And then you can switch the configuration fetched from your macro property in the macro partial view loading different views depending on the selection.
Thank you for all of the responses. I wonder if I am looking at this incorrectly. My hope is to develop a solution that is as easy to use on the Administrative side as possible, without having to know Node ID's, or much coding to implement. So I would like to build Macro's I can package and deploy for the end user. These Macro's need to have parameters that the end user can configure. For example, the Macro may have a parameter for an Administrative Page. Currently there is already a way to do this in Umbraco (If I understand correctly), and if you choose this Parameter Type (I believe it is the content picker), the user will be shown a list of the sites nodes and they can select one.
My problem is that if I use the Model I created (by using this in the cshtml file:
I would like to have access to the parameter value so I can write some logic around it in the Macro.
I understand that I can create parameters via the Model and Controller, and that I can create my own Parameter Type in Umbraco, however having the user have to manually type out the Node ID (something that is obfuscated and may be difficult for them to find) may not be ideal.
I think I may be resigned to not create my own Models/Controller, and instead use Umbraco's views to make a direct call to my DLL to get my business objects, then interface with Umbraco's Model to get the stuff I need.
Architectural questions for building a system on top of Umbraco, using Razor
Hello,
I would like to build a platform with various tools and add-ons on top of Umbraco. The vision is that I would have Umbraco installed at various locations, who could in turn install various plug-ins and packages that would provide additional functionality while leveraging the benefits of Umbraco such as the CMS, security, blogging, and other features. Each of the plug-ins/ packages I would provide would pull their data from a back end system that I would support. I am planning on creating a set of WCF Services for each of these plug-ins which would allow for saving and retrieval to the back end system.
I would like to create these plug-ins/packages using Umbraco 6 to take advantage of the MVC Razor support. My thought is that if I use Razor, an administrator might be able to change the cshtml files to fit custom scenarios without impacting future builds, customizing the view for a particular need (i.e. in one instance a control may need to be rendered as a table, in another it may need to be rendered as a set of div tags, etc).
I am, however, running into a bit of a stumbling block on deciding how to architect everything.
For the purpose of this example, I would like to work on creating a plug-in/package that would be a simplified News service (I know, there is already a News package in Umbraco, but I need a simple example). I would need to have three or four controls.
1. News Player – A control that is able to show 4-5 news items, and cycle through them using a pager.
2. News Grid – A grid that shows all of the News Items, with the ability to page through past News Items and sort the Grid.
3. News Administration – A control that allows an Administrator to enter new News Items, delete old News Items, etc.
4. Configuration – A control for the Umbraco Backoffice which will allow me to set up the WCF configuration in the web.config to talk to the back-end system.
I believe I will create the Configuration Control using a traditional ASP.NET User Control for ease of use and simplicity. Everything else, I figure I will create via MVC and Razor scripting.
I would like to be able to pass parameters into the News Player and News Grid controls. These would be for things like, when rendering the News Player providing a link to where in the site the News Grid is located. This way the News Player can have a link to the News Grid, and when the user is viewing the player, they can click a link to get to the Grid. In addition, the News Grid and News Player should be passed a parameter on where the Administration page is located, so if the user has rights to view the Administration page they will have an option to click a link to get there. In my mind, these controls will need to be Macros so we can pass a ContentPicker parameter, and the view would then use Umbraco’s code base to create a link to the other node, check security, etc.
As I have been working on this, I am stuck at a cross roads at how to architect this.
From what I understand, I can create my Surface Controllers one of two ways.
1. Standard Surface Controller
If I create this as a standard Surface Controller, I would create the DLL, install it in the Bin folder, and create all of the Views (cshtml) via Umbraco’s interface. It would allow me to have the Views be somewhere that an Administrator could alter them. This way if they needed to change the grid from a table layout to a div layout, it could be done.
I have tested, this, and it seems to work. I have the following code:
Controller:
Model:
public class NewsItem
{
#region Constructor
public NewsItem(int newsItemID, string title)
{
this.NewsItemID = newsItemID;
this.Title = title;
}
#endregion
#region Public Properties
public int NewsItemID { get; set; }
public string Title { get; set; }
#endregion
}
View (under Partial View Macro Files):
Template:
Everything works well.
However, when I try to turn it into a Macro and use the Macro in the template:
I generate an error:
Error loading Partial View script (file: ~/Views/MacroPartials/NewsPlayer.cshtml)
I believe it doesn’t like the Model that was passed in, it is as if it is by-passing the controller.
2. Plug-in Surface Controller
The other way to do this is to create a Plug-In Surface Controller. To do this, I simply add an attribute to the controller:
[PluginController("GovAP")]
Next I place the views in the appropriate area of the Umbraco site:
App_Plugin/<Area>/Views/<Controller>
The View seems much the same.
When calling the code from the Template, it would look something like this:
@Html.Action("NewsPlayer", "NewsSurface", new {area = "GovAP" })
This works fine.
The problem I see is that if I use the Plug-in approach, I don’t see an easy way to pass in variables via Macros. I would like the user experience from Umbraco’s back office to be able to add a component, and simply have it pull up a drop down of all of the nodes in the site and select the node that has the Admin features for the control, or the Grid version of the control, etc. With the Plug-in, I can’t see the ability to do this.
With the non-plugin approach, you can create a Package of all of the macro’s, scripts, etc. That is great. However, it seems that I am unable to actually create a macro, use the macro, or use parameters passed in with the Macro, with the view I create. Is this because I can not use a Custom Model with Macro’s? What is the best way to set this up so an Administrator can use Umbraco to easily fill out these Parameters?
If I want the ability for the Admin to modify the views, am I best using Partial View Macro Files? Would I be better off using a Plugin?
If I use Partial View Macro Files, can I use a Custom Model? If not, what is the best way to gain access to my back end models? Do I just make a call to my BLL using Razor, and access it that way? If using a Custom Model, can I some how access Macro Parameters? How is this best done?
If I am creating a package, is there any way I can privately deploy that package to my webserver, and have Umbraco check that server for an updated version?
You can simply pass your macro parameter values in your macro view:
You must still extend your NewsPlayer action with a parameter:
This is just a simple example, but may that help?
Thank you for the response. It wasn't quite what I was looking for, in that I was hoping to have it be a Macro so that I could take advantage of Macro Properties in Umbraco, and allow the Administrators to interface with the views using a simple and powerful Gui. For example, if I would like the Node ID of a different page passed into the View, I would like the use to do this via the Macro's properties, where there is a simple drop down for them, rather than having to know the Node ID and pass it in through the function call. Thank you for the suggestion though.
Do you mean creating an own data type (as dropdown) to use as macro property?
Creating an own data type is simple but I don't know how to create data types that can be used as macro property...
That one may help:
http://our.umbraco.org/forum/developers/extending-umbraco/40878-Umbraco-6-Custom-Macro-Param-Type-Broken
And then you can switch the configuration fetched from your macro property in the macro partial view loading different views depending on the selection.
Thank you for all of the responses. I wonder if I am looking at this incorrectly. My hope is to develop a solution that is as easy to use on the Administrative side as possible, without having to know Node ID's, or much coding to implement. So I would like to build Macro's I can package and deploy for the end user. These Macro's need to have parameters that the end user can configure. For example, the Macro may have a parameter for an Administrative Page. Currently there is already a way to do this in Umbraco (If I understand correctly), and if you choose this Parameter Type (I believe it is the content picker), the user will be shown a list of the sites nodes and they can select one.
My problem is that if I use the Model I created (by using this in the cshtml file:
I don't have access to this parameter.
I would like to have access to the parameter value so I can write some logic around it in the Macro.
I understand that I can create parameters via the Model and Controller, and that I can create my own Parameter Type in Umbraco, however having the user have to manually type out the Node ID (something that is obfuscated and may be difficult for them to find) may not be ideal.
I think I may be resigned to not create my own Models/Controller, and instead use Umbraco's views to make a direct call to my DLL to get my business objects, then interface with Umbraco's Model to get the stuff I need.
is working on a reply...