I'm working on a site that contains a collection of print journal microsites. Each journal microsite has it's own UI. In addition to custom pages within each microsite, each one will contain a fixed set of pages dealing with login, registration, subscription, etc. They look the same for every journal but they should be rendered within the context of the journal (header, navigation, etc).
I'd like these pages not to exist in Umbraco content tree since they'd have to be duplicated for every journal. Effectively, I'd like to render a "default" Umbraco page from the current journal (defined by hostname) along with a custom model.
I've tried using a SurfaceController with a custom route. Can't figure out if it's possible to render a full page from a SurfaceController. Here's what I've tried. When the view renders, a simple Umbraco.Field() call fails with a NullReferenceException. Even stranger, trying to inspect CurrentPage never returns. Just keeps spinning.
var page = Umbraco.TypedContent(rootId); var model = new RenderModel(page, CultureInfo.CurrentCulture); return View("Register", model);
I could use a RenderMvcController but then I need to have pages exist inside the content tree.
Where abouts is the post being made from? a View or Partial. If it is from a partial i think you need to return partial view rather than View. Charlie :)
If you want to use the RenderModel i would suggest to use the RenderMVCController because it uses it by default. Also it should be used if you want to do your stuff when the node gets rendered.
But in general it's no problem to call Umbraco.TypedContent(id) to get a node in a surface controller. I'm currently doing this some times in a small project. The only difference is that i call the methods of my surface by @Html.Action() in my views and also returning custom models.
Yeah, I didn't want to use RenderMvcController because I don't want these pages in the content tree since they are going to exist for every journal. I've setup a "default page". All of these profiles pages will render this default page with a different template. As you can see in the code block above (which is for a register form), I retrieve the default page, create a RenderModel and then render the "Register" template. In the case of a subscription page, I'd render the same content item but with a "Subscribe" template.
I've routed to the SurfaceController actions without a problem. I can retrieve an Umbraco content node as well. The problem comes when I render the content item with a template. Any references to CurrentPage timeout and the Umbraco helpers fail. I believe it's because the UmbracoContext isn't initialized since I'm not routing through the UmbracoModule.
You use the SurfaceController so you route "through" Umbraco.
How does your template look like? Do you use the @inherits Umbraco.Web.Mvc.UmbracoTemplatePage? That thing gets you access to the Umbraco helper and some other stuff.
No, I've created routes directly to the surface controllers. I don't want to use the default routes for SurfaceController since they aren't friendly at all (/umbraco/surface/{controllername}/{action}/{id}). Not to mention there isn't a separate content node for each of these pages.
I had access to the Umbraco helpers like Umbraco.Field but the call to it fails with a NullReferenceException. My navigation also failed as all references to CurrentPage timed out.
At this point, I've given up and created a document type named "Profile". It requires that I have a content item for each of these pages in every journal. Each page will use a different template and I'll take advantage of the template action methods in RenderMvcController.
Well... maybe you don't think about the adequate strategy for the task you want to accomplish.
As far as I understand, you have several trees in your content section, one for each journal. Additionally you have a separate tree for registration, login etc.
In your template all you have to do is to determine the return url, and determine, in which tree the return url resides (node.AncestorOrSelf(1) gives you the root of such a tree). Now, if you have that information you are able to render different links to different css files. That way you can use ordinary Umbraco pages for registration and login and make them look different for each microsite.
You have to create the links to the registration pages using a partial in order to determine the return url. But that is a a really easy task.
Hi, We've done something similar and we used a custom route so it didn't run through Umbraco at all, we just wrote it like a ASP.NET MVC standard controller:
Render a full page from SurfaceController
I'm working on a site that contains a collection of print journal microsites. Each journal microsite has it's own UI. In addition to custom pages within each microsite, each one will contain a fixed set of pages dealing with login, registration, subscription, etc. They look the same for every journal but they should be rendered within the context of the journal (header, navigation, etc).
I'd like these pages not to exist in Umbraco content tree since they'd have to be duplicated for every journal. Effectively, I'd like to render a "default" Umbraco page from the current journal (defined by hostname) along with a custom model.
I've tried using a SurfaceController with a custom route. Can't figure out if it's possible to render a full page from a SurfaceController. Here's what I've tried. When the view renders, a simple Umbraco.Field() call fails with a NullReferenceException. Even stranger, trying to inspect CurrentPage never returns. Just keeps spinning.
I could use a RenderMvcController but then I need to have pages exist inside the content tree.
Any recommendations?
Where abouts is the post being made from? a View or Partial. If it is from a partial i think you need to return partial view rather than View. Charlie :)
I'm not even concerned with an HTTP post at this point. I'm just looking for a way to render a fixed Umbraco content item with a custom route.
If you want to use the RenderModel i would suggest to use the RenderMVCController because it uses it by default. Also it should be used if you want to do your stuff when the node gets rendered.
But in general it's no problem to call Umbraco.TypedContent(id) to get a node in a surface controller. I'm currently doing this some times in a small project. The only difference is that i call the methods of my surface by @Html.Action() in my views and also returning custom models.
How do you call the surface methods?
If you want to add completly new routes you have to add them to the routestable. Maybe this will help you with this: http://our.umbraco.org/documentation/reference/mvc/custom-routes
Yeah, I didn't want to use RenderMvcController because I don't want these pages in the content tree since they are going to exist for every journal. I've setup a "default page". All of these profiles pages will render this default page with a different template. As you can see in the code block above (which is for a register form), I retrieve the default page, create a RenderModel and then render the "Register" template. In the case of a subscription page, I'd render the same content item but with a "Subscribe" template.
I've routed to the SurfaceController actions without a problem. I can retrieve an Umbraco content node as well. The problem comes when I render the content item with a template. Any references to CurrentPage timeout and the Umbraco helpers fail. I believe it's because the UmbracoContext isn't initialized since I'm not routing through the UmbracoModule.
You use the SurfaceController so you route "through" Umbraco.
How does your template look like? Do you use the @inherits Umbraco.Web.Mvc.UmbracoTemplatePage? That thing gets you access to the Umbraco helper and some other stuff.
No, I've created routes directly to the surface controllers. I don't want to use the default routes for SurfaceController since they aren't friendly at all (/umbraco/surface/{controllername}/{action}/{id}). Not to mention there isn't a separate content node for each of these pages.
I had access to the Umbraco helpers like Umbraco.Field but the call to it fails with a NullReferenceException. My navigation also failed as all references to CurrentPage timed out.
At this point, I've given up and created a document type named "Profile". It requires that I have a content item for each of these pages in every journal. Each page will use a different template and I'll take advantage of the template action methods in RenderMvcController.
Well... maybe you don't think about the adequate strategy for the task you want to accomplish.
As far as I understand, you have several trees in your content section, one for each journal. Additionally you have a separate tree for registration, login etc.
Contents
Journal 1
Subpage 1.1
Journal 2
Subpage 2.1
Journal 3
Subpage 3.1
LoginService
Registration
Login
Failed Login
Forgotten Password
In your template all you have to do is to determine the return url, and determine, in which tree the return url resides (node.AncestorOrSelf(1) gives you the root of such a tree). Now, if you have that information you are able to render different links to different css files. That way you can use ordinary Umbraco pages for registration and login and make them look different for each microsite.
You have to create the links to the registration pages using a partial in order to determine the return url. But that is a a really easy task.
Hi, We've done something similar and we used a custom route so it didn't run through Umbraco at all, we just wrote it like a ASP.NET MVC standard controller:
http://our.umbraco.org/documentation/Reference/Mvc/custom-routes
Using the umbraco API we were still able to grab content out of Umbraco for the nav etc
A few things have changed in 6.1. Don't know if they are helpful in this case, but it might be good to know about: Change the default controller.
In 6.0.7 and 6.1.2 it will be possible to use a surface controller for route hijacking: http://issues.umbraco.org/issue/U4-2342
Jeroen
Steve, that's exactly what I'm trying to do. Could you share a bit of your controller and view code?
Thanks Jeroen. I'll look into that.
I'm super busy today I'll try and get you an example after work
Steve
is working on a reply...