I am a little ashamed for asking so many questions, but I really want to learn.
In Sipke's blog a webshop is created. There is one specific question that boggles my mind when trying to do something similar.
Let me spell out the basic requirements:
User registration form and login, etc. This one is covered by the blog and it works nice.
Creating product parts and so on. This one is covered and no problem there.
Ordering by filling in an order form and making the payment. See down
Having the order page maintainable by customer. See down.
Viewing your own orders and their status. See down
Maintaining customers and orders from backend system. This one is covered by the blog and I need to do some work there yet.
As for items regarding creating orders and viewing your orders. I have followed the approach for creating records and using standard MVC controllers. But then I encountered problems:
Menu for orders page. This I had to do manually after installing the module.
The order page itself. I had to create the view including title and so on. But I can imagine a customer wanting the order page on another menu and with a different title. And maybe add even some own content to the ordering page. This I couldn't achieve by using standard MVC approach. So maybe I am using the wrong approach here. So I was thinking about using contentparts for creating an order and displaying them and using the drivers and handlers for that. But before I go down that road and refactor everything I want to know if that is the right approach. A downside could be that once the module follows that route it can then not so easily be reused with customers that have other cms's capable of hosting an MVC3 module.
So when to use drivers, handlers and contentparts and when to use standard controllers and views.
You should use Drivers and Parts (with Handlers if needed) when you want to create functionality for content items. E.g. if you want to display a custom media with all products, you could create a Part (together with its Driver, etc.) to handle that. Read the docs on Parts.
If the functionality is not tied to content items the most possibly you want to use the standard MVC toolbox, it's fine. Look at the built-in modules how they do that. E.g. the Blog module uses controllers and views to show the admin UI, but has parts to enhance the functionality of for example the Blog content type.
To make things more complicated you can employ ad-hoc content items to build a page that you'd normally do with simple views, but that's an advanced topic :-).
Related
So I have a highly customized CMS type system where users can manage content on pages. For the most part everything is templatized, however, the home page is unique in so much that it has additional, editable content that a regular page does not have.
The two solutions that I thought of for this are:
1) I could add a new model, controller, and table in the DB making this an entirely new component. However that seems like a lot of trouble to go through for one page.
2) I could add the missing columns for the home page to the general "pages" table, but again that seems sub-optimal as the additional columns would only ever be used for home page.
What's the best way of handling a situation like this? Is there an additional way that I haven't thought of?
IMHO it really depends on the site and how much differs b/n the homepage and other pages as well as what DB-interaction the homepage has. Kind of a tough question to answer generally.
One thing I've done in the past that has worked well is to have a "Home" record in the CMS tool (assuming there's a 'content' field you can access). Then build that custom controller/view for the homepage -- it is the homepage after all.
Add in your custom functionality, custom layout, formatting, etc. And pull that 'content' field from the 'Home' record in the CMS and insert it where relevant.
That way, the CMS staff can still tweak the homepage messaging, but you maintain full db-interactivity over it.
Hope that makes sense.
I wouldn't advise against #2. Seems wasteful.
I ended up just creating a Model, Controller, table, etc. for generic 1-off pages that are flexible as I suspect that I'll have need for additional stand alone pages in the future. The home page is just one of those now with a special route a method in the controller.
I am just starting a project and the wireframes are ready. But looking at the wireframes it seems that the primary goal was to reduce the number of pages and to include maximum functionality in to a single page.
Taking an example of an organization, the top portion of the page will show the organization details, below that at the left we have an division structure as a tree view, clicking on a division will populate the employee list on the right as a table, and when you click on an employee it will populate the employee details below.
Current wireframe looks something like this:
End user is happy as they can see the entire functionality on a single page and doesn't need to navigate to another page.
But this design reminds me the screen of some old desktop application and I feel that this page is unnecessarily complex- I want to split this in to multiple pages (at least in to three). Also, I am using MVC 4 and splitting this in to multiple pages will definitely help me to reduce the complexities during implementation.
But before arriving at any conclusion and raising any concern, I would like to know what you guys think. Some articles related to User experience are also welcome.
Here's what I think.
Whether the design above is 'right' depends on the target audience and the type of work / business process they need to carry out. There may be a strong business argument for being able to see all the information (org details, divisions, employees and employee details) on one page. It is not unusual to see a lot of information displayed in a page with a lot of interactivity - users expectations have increased because of consumer sites such as Gmail.
The users might find it frustrating if it was broken out into different pages.
To put it another way, I don't think there is a valid technical justification for making the designer change the UI above to split it into different pages.
You would be able to build the UI above in MVC as a single page web application. You will probably need to implement a lot of controller actions to support ajax calls. You're almost certainly going to end up using a lot of JQuery and you are probably also going to end up with a significant amount of JavaScript to write. Also, you'll need to make sure the designer has made good decisions around the sizing of the page. Is it going to be fixed width or dynamic for instance? You'll need to emit well structured HTML in order to achieve that solely using CSS (which I would strongly advise you do).
Lot's (if not most) of the current Web frameworks provide an admin module for basic CRUD operations, but I find the ones I know usually very limited...
So, my question is, which Web framework out there provide the best administration backend?
By the best, I mean namely:
Domain objects that can be heavily polymorphic. Attributes/relations defined in a class appear when editing a record/instance of any of it's subclasses (and sub-subclasses, and sub-sub-subclasses, etc).
Abstract classes. It's ok to have abstract classes anywhere in the domain classes' hierarchy. Their attributes and relations also show in the records/instances of all descending classes.
Relations. Allow to edit (out-of-the-box) the records/instances that have many-to-many relations, and relations with associative classes (e.g., django calls these intermediate models)
Extension. Allow to extend the admin so that we can use our own "UI controls" for specific domain objects. Some information is just too "exquisite" for an out-of-the-box form-based control to work in a suitable way.
UI Components. Instead of having to choose between using all of it or none of it, it'd be nice to have generic "UI controls" that one could reuse from within any page of the website, to edit specific domain objects.
Programming language is not an issue at this point, although I lean towards the languages (or frameworks) that allow me to express the most information at the domain model level (and that the admin module can then use to give me a richer UI).
I've been playing with Active Admin and Rails Admin for a couple of Rails 3.1 projects I am working on. While both are nice, I've migrated more and more to Rails Admin. I've found it easy to customize, it does a very nice job with associated models, and has a great default UI.
Rails Admin
Definitely good old WebObjects with it rule system called DirectToWeb. It generates everything at runtime based on rules. By default it can display all your entity's properties and relationships.
I guess that every current web framework will offer something like scaffolding, but often times, the work begins as soon as you change your model.
Check out this post and this teaser about the latest DirectToWeb-based framework, ERModern. You use nearly zero code for what you see in the video and you can build entire applications around it. It was sponsored by the iTunes team.
Edit for your bullet points:
Abstract classes and domain objects that can be heavily polymorphic - You handle these using rules.
Editing relations - No problem, it only depends on the design of your components. If you use ERModern, you get this for free.
Generic UI components - This is exactly how DirectToWeb works. You use (or define your own) generic components that display themselves according to the current entity (an object inheriting from EOEnterpriseObject) and the rules that fired for the current state (the D2WContext, essentially a big dictionary).
You can see all of this in action in the 45 minutes long ERModern Intro Video.
This isn't an easy question to answer.
You never specify what language you want to use, and you named some features, but how much of these features do you want.
I mean I could suggest a number of frameworks and tools for ASP.Net MVC or Web Forms but what if you're a PHP developer or a Java developer?
I could suggest SharePoint (and I generally dislike sharepoint, but everything you want is in SharePoint), but then the question to ask is.
How much flexibility and freedom do you want to customize or how much do you want the framework to do and you just be a code monkey.
So I will give you just my opinion.
I use ASP.Net MVC for my custom apps. It does all of what you want and allows me the most freedom to create and extend with tools if I so to do so. Plus out of the box there's a user databse with roles I can easily create out of the boss once I run the app for the first time.
Also CRUD is completely easy and straight forward out of the box. just check it out http://www.asp.net/mvc there's a tutorial section that goes through what you're wanting that you could complete in half a day.
Then there are some OR/M like NHibernate, Entity Framework, Subsonic use www.google.com to find tutorials for these if you're not familiar with them.
Then there's SharePoint it has a learning curve but once you get past it it's pretty straight forward as it's easy to pinpoint bugs, focus on the business logic and not worry aobut data base schema (as you don't even need to touch a database).
I love WebObjects.
WebObjects -> EntityModeler -> Wonder -> ERD2WModernLook -> ERAttachment --> ERRest
Bam. Done.
I have a question about how to design my controllers properly.
Project is fairly simple: blog, immage gallery with categories and images inside them, news secion.
However I don't know how to organize my controllers for this because I want to make somewhat admin panel where administrators can edit, add and modify these things. I've came up with 3 scenariosu so far...
Admin panel will have links to site/controller/edit, but layout for these action results will be different from standard one.
Admin controller will have all these actions like BlogAdd, BlogEdit so that url will be something like /site/admin/blogedit.
Create copies of Blog controller in admin folder so url will be like /site/admin/blog/edit - i sense problems with routing since 2 controllers with same name does not sound like a good idea, however I like ho URL looks in this situation.
What I'm trying to make is CMS somewhat similar to wordpress, where blog creation,editing and deletion is completely separated from default blog itself.
I suggest you stop thinking about URLs and Controllers being a 1->1 relationship. This will make things MUCH easier and less confusing. You can make the URLs work however you want with MVC's routing mechanism and there's no reason to restrict your controller design/organization because of the URLs you want, because you can always adapt the routing to with with the URLs you have in mind.
While building the website, just focus on the controllers (and the general interface) and ignore the URLs until you get to that point, and then when you come up with a good URL scheme go into the routing system and add the routes to connect to your existing controller actions as you want.
Once you code out your blogging engine you will have a much better idea of the user workflow and will probably find different ways to organize your URLs, and you can then reorganize your URLs without touching the controllers themselves.
As to your first requirement:
There are two ways to do this depending on your end goal. If your goal is to display the same core content, but have different user options available (different overall layout, additional buttons on the page, etc..) then the best idea is really to just pass in an IsAdministrator property in your view model, and make the slight changes to the page based on if that's true or false. The reason is because you still (most likely) want the core of the page to be the same, and this keeps you from duplicating code that is related to the core data (data that's being displayed for both admins and non-admins).
Edit: So in summary, organize your controllers based on what makes it easier to develop with, not based on how the user interacts with the system with. You can always change the latter, changing the former is harder and will make maintenance annoying.
You can create Areas in your MVC project and have your admin functionality in a controller in your admin area.
This will allow you to easily seperate your administration functionality from your general blog functionality.
That's how I'd do it.
Why don't you keep the routes the same and handle the different roles via security? For example:
/blog/name-of-topic/view to view a topic (all users)
/blog/name-of-topic/edit to edit a topic (only enabled for logged in users)
/blog/add to create new topics (only enabled for logged in users)
You can handle these actions in a single controller and decorate the actions that require logged users via the [Authorize] attribute. Same thing with the links on your views, you would enable the links to edit and add topics only to visible users.
You could still have a separate panel to allow admins to hit the aforementioned add/edit links .
We're building about 10 ASP.NET MVC sites which have a common set of features (and corresponding URLs, Routes, Controllers, Actions, and Views). The sites will also all share a base set of domain objects (e.g. users, companies) and base attributes on those objects (e.g. name, address, etc.).
But each site will also be highly customized and extended from the base. For example, our site for large, public companies will have "Subsidiary" and "Stock Symbol" fields on the Company domain object, while our site for startups will have a "Venture Firm" and and "Funding" attributes. Look and feel will also vary considerably, although we're trying to keep HTML as consistent as possible (modulo extra form fields for extra domain object attributes, etc.). We'll also be overriding images sparingly, so we can, for example, re-use the same button graphics across sites.
Anyway, we're trying to figure out how best to factor and architect things so that we can reuse as much code and as many tests as possible without limiting our freedom to add per-app attributes and vary the UI between apps.
I'm familiar with how to handle limited-customization multi-tenancy like you find in StackOverflow/SuperUser/ServerFault (or MSDN/TechNet for that matter), where the UI is a little different and the data model is more-or-less identical. But when the models and UI are very different (but inherit from a common base), I'm less sure how to proceed.
I'm less worried about operational issues, since we'll probably be running each site in a separate appdomain and hosting them on separate databases. I'm more worried about reducing long-term code maintenance costs, increasing agility (e.g. easy to add new features to the base without breaking derived apps), and realizing short-term dev-/test-cost savings as we build our 2nd, 3rd, 4th, etc. site.
I'm looking both for high-level guidance and suggestions, but also concrete suggestions for how to make that guidance real using modern ASP.NET MVC practices.
I realize this is a very general question, but for starters I'm looking for both high-level guidance as well as concrete tips-n-tricks for how to apply that guidance with ASP.NET MVC, including things like:
recommendations where to split base/derived across Visual Studio projects
source control tips to avoid forking
database schema tips (FWIW, our databases are all small-- under 10K rows per table, so dev/test cost is more of an issue than DB perf)
tips about re-using Controllers/Views/etc. corresponding to the "base" model attributes, especially re-using UI for things like "new customer" forms which will have a mix of base and derived attributes.
Anyone have good advice for how to architect a multi-tenant app like this?
Here's what we do, and it works pretty well for about 8 sites currently.
Define a core MVC project for your Controllers, ViewModels, HttpApplication, routes, etc. This will compile into a DLL and compromise the bulk of your site.
Create a basic set of default views, scripts, images, etc. for your site. These will server as defaults for your individual sites.
Per client, create any custom controllers, routes, etc that you'll need in a project that compiles to another dll.
Also per client, recreate any views, scripts, images that you'll want to use.
To make the above steps work together you'll need to write a little glue. The first piece of glue is a custom view engine. You'll want to customize the standard view engine to first look for views in your client-specific folder, and then the default folder. This lets you easily override the default layout per client.
The second method of getting everything working is to have your core application load the routes, controllers, etc from your client specific assembly. To do this I use the Managed Extensibility Framework (MEF) to expose a single Register method. Calling this method on my client assembly code registers the routes and any other client-specific needs.
Here's a general view of what my site folder structure looks like, with SiteContent being checked for views first:
- AppContent
- AppContent/Static
- AppContent/Static/Images
- AppContent/Static/Scripts
- AppContent/Static/Styles
- AppContent/Views
- AppContent/Views/Shared
- SiteContent
- SiteContent/Static
- SiteContent/Static/Images
- SiteContent/Static/Scripts
- SiteContent/Static/Styles
- SiteContent/Views
- SiteContent/Views/Shared
- web.config
- Global.asax
I have helpers that I can use like SiteImage and AppImage for use in my views. Also, I make each of my client sites use certain specific names for their master pages, that I don't ever define in my AppContent defaults.
I realize this is a rough overview, but it is working well enough for us right now.
I'm involved in a similar type of "suite" of projects currently which is focused on allowing customers to apply for products online but have very similar requirements for what information to collect, where the only differences are around product specific pieces of information or slightly different legislative requirements.
One thing that we have tried to do is create pages (model, view and controller combinations) that are reusable in themselves, so any application can use the page to capture information but redirect to the next page which may be different depending on what type of product is being applied for. To achieve this we are using abstract base controllers in the form of the template method pattern that contain basically all the required controller logic (including action methods with their applied action filters) but then use abstract methods to do the specific stuff such as redirecting to the next page in the process. This means that the concrete implementation of the controller used by specific application page flows may contain only one method which returns a RedirectToActionResult corresponding to the next page in the flow.
There is also quite a bit of other stuff that handles going backwards and those kinds of navigational things, but with the help of action filters you can get it set up that you don't have to worry about it once you get it up and working.
There are also base model objects which contains common functionality, be it validation logic or state persistence logic.
The data captured during the application process is persisted in database as xml serialized model objects which can then be pulled out and de-serialised once the application is completed and spat out in whatever format to whatever system the backend operations staff use to process applications.
The implications of this is that we have a project structure that consists of a base dll that contains top level abstract classes, interfaces and utility classes as well as html helpers, action filters etc. Then we have mvc projects which contain the concrete implementations of the base controllers, models etc as well as the views and masterpages.
The hardest thing is sharing views and I don't think we have properly got this sorted yet. Although with MVC 2.0 containing Areas I think this will become less of an issue but I haven't had a good play with it yet. (see Scott Gu's post on 2.0: http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx)
One thing I have POCed that looks like it will work is using a base MVC project to contain common views and then extending the default view engine to search that project on the web server when looking for a view to render (which is quite easy to do). Areas though is a far nicer solution.
As for source control, we are using svn and I think you are reasonable in being concerned about branches. It is not something that we have had to deal with yet, but we are probably going to go with git as it seems to make the process of branching and merging much less painful.
Not sure whether this helps you much but I would definitely recommend keep in mind abstract controllers and models, and also look at how you can use html helpers and and partial views to group similar pieces of functionality.
Mike Hadlow goes into good detail on how to accomplish this:
http://mikehadlow.blogspot.com/2008/11/multi-tenancy-part-1-strategy.html
One way to do this is to use branching in a source control system.
The main branch is for the common functionality. You then have a branch for customization and can merge changes out to the customization or back to the main branch.