Nested layouts in Orchard pages - asp.net-mvc

I'm trying to migrate an existing ASP.NET MVC 3 website into Orchard, so I can continue to build the site while taking advantage of the extended features offered by Orchard. I'm attempting to wrap the entire existing site into an Orchard Module, so I can keep all the existing functionality intact, and continue adding features, or porting old features into the new paradigm as needed.
The main issue I'm having with a straight copy into Orchard is that I've taken advantage of the Layout hierarchy in MVC 3 to specify the same parent layout for related pages, which in turn may have its own parent layout, and so on.
When I copied in my existing views, I get the error that Layout is a read-only property on the custom Orchard WebPageView, but when I change the base view type back to the standard MVC 3 base type, the paths do not match up to my views because of the Module folder structure.
Is the ability to specify nested layouts simply not supported for sites running in Orchard, or is there a built-in work-around that I'm missing?
Thanks!
-J

Orchard's layout system predates MVC's and works a little differently. I'm afraid you will have to refactor things a bit. The views in Orchard rely on the idea of a shape, which is a dynamic object analogous to a view model. When the time comes to render a shape, the system looks for the most appropriate template to transform it into html. Most controller actions return a shape result that will be rendered as a child of the content zone that must be defined in the layout shape. The layout shape rendering can be changed by specifying alternates for it (see http://weblogs.asp.net/bleroy/archive/2010/12/14/switching-the-layout-in-orchard-cms.aspx).
So in the end Orchard doesn't use the sort of inverted master-page-like layout system that Razor/ASP.NET Web Pages/MVC3 promotes. Instead you use shapes and their alternates to get similar results, but the viewpoint is different as shapes get added into nested containers rather than have contained objects specify what they get inserted into.

Related

How can you store all of the files associated with a Rails view component in one place?

As much as I love Rails it has a tendency to scatter the components of a particular view far and wide across the file system. And this gets confusing.
Rails' view of a web page
Rails has a view of a webpage that's driven by layouts, templates and partials. I think this stems from the old PHP way of looking at things where you view the page as a document and some parts of the document need to be re-rendered in other documents.
However a modern web-page is far less a document and far more a grid on which a series of components are laid out. Each component does different things and has its own styling, logic and layout. Components should also be easily usable elsewhere.
This is similar to the concept of a partial except that we're saying that that partial should also contain the details of its styling and logic, not just the HTML (I believe this is how React views the world).
A component-driven view of a web page
For the sake of simplicity I'm going to say that an actual HTML view is made up of nested components where each component has:
an HTML template
a ruby view-helper file - ideally, isolated ViewObjects
a CSS file
a file with RSpec tests
By default, rails scatters the parts of a single component all around the file system
At the moment, these are scattered far and wide across our Rails project which makes it really hard to track things at scale and be certain of what relates to what
the view logic is in /helpers (or since we've started using ViewObjects, /view_objects/...
the html is stored in /views/...`
the CSS is in /assets/stylesheets/...
the tests are in /spec/...
With everything all over the place it makes it hard to ensure that the logic, tests, styling and templates are all well componentised and they have a tendency to start spilling over each other's responsibilities.
Contrast this to our front end logic (Angular)
Our front end is entirely Angular. We've made it our own custom setup over the years but each Angular component has its own directory and in the directory is (let's say for a contact form):
contact_form/contact_form.js - the directive (logic) for the component
contact_form/contact_form.html - the HTML template for the component
contact_form/contact_form.css.scss - the CSS for the component
(ideally we would also have tests in here but we haven't got that far yet
Is there a way to group the assets for a Rails component in the same directory?
I would like to do the same with the Rails components we use. I'd like to have a single directory for each component (let's say a contact form) that includes:
/contact_form/contact_form_view_object.rb - the ViewObject that controls the logic
/contact_form/contact_form.html.haml - the HTML template
/contact_form/contact_form.css.scss - the CSS for the template
/contact_form/contact_form_spec.rb - the RSPEC files for the component
This way the responsibilities of the component and the associated tests and styling are far more explicit and it becomes easier to grow the project without getting into a huge mess of intersecting responsibilities.
Is this possible though?

Why Orchard doesn't have model view controller?

I am working with orchard. writing such a project is my dream!.. so i started a research a bout that. which interested me about orchard, is while orchard is mvc project but why it doesn't have any model , view and controller in his web layer solution? does it use CleanArchitecture or some specific architecture like this ?
i tried to know about this case in orchards documents but i didn't find any description about it.
Actually, Orchard being an MVC based project, it intrinsically does have models, views and controllers. But it provides much more than that.
The key thing to understand, in my mind, is that at the very core, requests are handled by a given controller, which builds a model, and returns a view that uses this model. What Orchard adds to that is how it builds up a particular model, and how it selects the view to display that model.
Consider requesting a content item by navigating to, say, a content item with alias "/about".
What happens is that the ASP.NET routing will kick in, which has been configured to match against aliases of all content items. The route for "/about" will be found, which is handled by the ItemController of the Contents module (modules in Orchard are conceptually the same as MVC areas). The ItemController will build a dynamic model for the requested content item, which is called a shape. The shape is an instance of the Shape class, which contains metadata about the shape, such as the name of the shape. Based on this information, Orchard leverages the view engine to select the appropriate Razor view to render the shape object.
So you see, all of the basic MVC stuff comes into play. Orchard simply adds a powerful infrastructure on top of it to provide an advanced and flexible rendering system, like turning content items into shapes, which are then turned into HTML via the view engine. But at the end of the day, it's primarily about controllers creating models used by views.

Battle-hardened strategy for naming files and folders in asp.net mvc projects

In French, a "donkey bridge" is some apparent difficulty in a subject to be learnt that throws off newcomers - the donkeys. The expression is used with patronizing assurance by educators who know the difficulty is apparent, not real, and the donkeys just have to cross the bridge.
Well I'm the donkey, and I'm having real trouble settling down with the folder structure and "virtual" urls of asp.net mvc projects. Urls are now a blend of pseudo-path information, encoded in routes, and arguments, that resolve to controller classes that, being classes, have no notion of their directory. So, it seems, there is no simple way of using relative paths/urls to reference static resources associated with a dynamic page: script file, stylesheet, razor view, images. .Net helpfully gives me default search locations for views, and default folders for "Content", "Scripts", "Images". I get the feeling they want me to file things by type. But this obliges me to invent file and subfolder names in each of these locations, then to hardcode the resulting paths in the controller and the view. Since a given controller generally has only a handful of tightly coupled views, and 99.9% of views have 1 script file and 1 stylesheet, all this name invention, and categorization by type, introduces needless brittleness and complexity, and masks any expression of what the project actually does.
Is anyone else fighting this? Is their a tried-and-tested strategy for naming in large mvc projects that
Expresses what the project does at the top level of the folder structure (or any level of the folder structure!).
Provides a default location or generated names for .cshtml, .js and .css, such that I don't need to search through code to find the names of associated resources.
Preserves the flexibility and decoupling of naming/indirection where this has proved useful.
I'm aware of areas as a way subdividing an mvc project into functional groupings, but this just seems to recreate the problem inside each area. I've looked at this method for customizing the search location for views, but there's no dynamic element. I've implemented a view engine to have fine-grained run-time control over the view path, which is fine if you're brave but I'm still unsure how best to use it, and I'm put off by the potential caching issues. For all the dissing of opinions, I'm particularly interested in answers addressing what I should do.
Thanks to all the downvoters, intolerant village folk. The donkeys that refused to cross the bridge are right, and they're all hanging out in a green field, munching happily on Nancy and building fabulous Owin pipelines. Feature folders are the future.
I agree with you that trying to arrange elements by type is usually problematic. For example putting C# interfaces for a customer and a product in the same "Interfaces" folder is not something I am keen on personally, I'd rather have a Customers folder and a Products folder, each with an Interfaces folder inside.
However, with MVC, there is a lot of enforced and unenforced convention in place which you will probably have to live with. As an example, if you have a controller called ProductContoller, it will automatically look for views in the Views\Product folder. So your product index.aspx/cshtml view is nicely segmented from your other index views.
For things like scripts and CSS, these are not enforced and technically you could put them anywhere, but it's a convention across many web frameworks to keep them in the same root folder. In some frameworks you would be explicitly allowing public access to certain folders to read files, so you'd want to do this for all scripts or CSS files together.
It's not an answer but I hope it helps.
then to hardcode the resulting paths in the controller and the view
No.
Use UrlHelper (Url property in controllers and views). Extends it with ad-hoc functions for resolving your specific urls, as this blog post do.
For resolving views, stick to MVC conventions as explained in Dorian's answer.

MVC 3 project structure

I am trying to find the best way to layout my MVC 3 project. When searching online I came across a suggestion that basically said right click on project and add area. What this did was create an area folder with same controller/view/model structure in the same project. This is not what I want. I want the flexibility of having separate projects. I will keep only the views in the main web project. Everything else in a separate project.
Towards that attempt I created a separate project for my controllers. Now I am stuck with pointing a controller action to a view. In all the online examples it was right click and add view. This being a class library project I don't have that flexibility. Where am I going wrong?
All examples that I have found including the ones I have gone through on Asp.net basically explain how to create study applications, which is only good for learning purposes. A large commercial application can't possibly have all the views/models/controllers in one project. Or is that the way it is supposed to go in MVC? I am not sure if doing everything with mouse clicks is also a good idea. In the webforms world also there were a lot of study-for-beginners applications that used mouse clicks to create basic CRUD applications, but in real commercial projects, we never used those methods.
What are your thoughts, guidance on this?
Thanks for your time...
MVC is based on a convention; the convention is you put all the views on /views, the models in /models and the controllers in /controllers. You can change the convention but it will not make your life easier.
From a conceptual point of view this does make sense. If you keep all domain logic and data access in separate projects all you are left with is the web related stuff, your controllers, view models and views. That's your MVC project.
Note that if you want to split off parts into separate projects you may find portable areas useful.
I don't see why you can't use the built in generators as a base for your views and controllers? Nothing says that you have to leave them as generated. I personally thinks that's it's really nice to get a base generated for me (with mouse clicks).
The MVC project is just a UI layer. It's madness to put logic in it for large scale applications. It's therefore usually fine to have one project for all the UI. It actually makes it easier to get an overview of the UI.
That said, there are ways to get a plugin based solution where you can move the controllers (, models and views) to class libraries. But it's not easy.
You need to create a virtual path provider (to find the views)
Make all views embedded
Modify the project file to get the "Add view" dialog etc.
Use areas (makes it easier)
Tell the BuildManager that your plugin DLL exists.
You also need to modify the virtual path provider to access the views from your plugin folders if you want to be able to modify the views during runtime in visual studio. Any change would otherwise require a rebuild of the plugin DLL.
Update
Video for MVC2 (MVC3 areas works the same): http://www.asp.net/mvc/videos/mvc-2/how-do-i/aspnet-mvc-2-areas
Do note that that video is for areas in the same project. Having areas in separate class libraries are more complex. The easiest solution is to use the portable areas as suggested by someone else.
Why keep only your views in the 'main web project' - I think you are missing the point with MVC.
It's the controllers that are your 'main web' part. They are what your users request and post back to, not the view.
The view is only there to provide a means to layout HTML for the controller to push to the browser.
The Models which I think should really be ViewModels, are there to provide substance (i.e. real data) for your views.
So you can see that the MVC layout really wants all three of these to be grouped sensibly together. Controllers interact with your user, get the view (the layout) and populate it with your ViewModel/Model (the data). This is your user interface, all three parts of MVC (if you go with the ViewModel anyway) are only for UI.
Where the data comes from, your real models and whatever you want to do with it can easily reside in a dll somewhere or on the other side of a set of web services or whatever.

What is an ASP.Net MVC View Engine?

There are quite a lot of questions on SO regarding View Engines in ASP.Net MVC, and about using "custom" ones instead of the "default" one. For me as a hobby programmer, the term "View Engine" is new, and I have not been able to understand what it means. So, my questions are:
What is a View Engine?
What does the View Engine do, and which role in the MVC pattern does it play? (Closely related to 1...)
What are the main characteristics/properties of the default View Engine that programmers want to change/avoid by switching to a different View Engine?
What are the main benefits of common other View Engines out there that developers are after when they choose to use a different one than standard? (I've seen the name "Spark View Engine" a bunch of times, and I bet there are others too).
When (in what scenarios) would I want to develop my own View Engine?
There, I think that is all I want to ask (for now). Give me View Engines 101! =)
The "view engine" handles the rendering of the view to html, xml or whatever content type it is created to emit. Within "MVC", it would be an aspect of the View (V).
Different view engines have different syntaxes, etc. to manage rendering. The decision to use another view engine is most likely very project/programmer specific. In some cases they may see an actual or perceived limitation of the default view engine; in other cases it may simply be a different design goal or focus.
As far as Spark goes, their focus is to be much more terse than the default view engine and to remain in HTML-like syntax as much as possible instead of dropping into ASP.NET script blocks.
As an end user, the only time you would want to create your own view engine is probably never. ;) It's not a task to be taken lightly, and you'll probably end up re-implementing functionality that already exists in an existing view engine.
Edit
OK. So are the View.aspx files part of
the View Engine, or is the View Engine
a set of classes that help choose
which View.aspx (or other type of
response) that should be rendered? How
does it work?
The MVC pattern tells you that your model, view and controller will be separate "things". In ASP.NET MVC, the default view engine uses the existing ASP.NET framework, which includes master pages, ASPX files, etc. Spark does something similar, but it's a different engine so it doesn't work exactly the same. So in a general sense the view files are not engine-specific, but the specific files, their layout on disk and their contents are view-engine specific.
In addition to wanting to completely replace the view engine (e.g. Spark), you also might make your own view engine just to make a small change to the behavior of the default view engine. You could do this by creating a new view engine that inherits from the default engine and overrides some behavior.
One common example is tweaking where the view engine looks on the hard drive for the .aspx files. For example, you might want to create a view engine that automatically switches which view.aspx file is used based on whether the user is on a mobile device.
See Mobile Web Sites with ASP.NET MVC and the Mobile Browser Definition File for a really good example implementation of this.
Update:
Scott just posted an updated ViewEngine implementation that has important improvements vs the initial implementation linked above.

Resources