erichexter/twitter.bootstrap.mvc

Goal with twitter.bootstrap.mvc short/long term

Closed this issue · 21 comments

I've been playing with this project a bit and find it quite useful for scaffolding basic CRUD for admin-purposes.

I have created a few generic components for things like:

  • paging using bootstrap paging
  • dropdowns for create/edit using valid choises provided in view data
  • search functionality for lists/paged lists
  • replacement of id values with clear text data from referenced objects in displays/lists
  • generic partials for actions on items in lists

Would you like things like this to be added to this project? If so I'd be glad to post examples and pull requests.

By adding more of these things this project could be ending up in an Naked Objects implementation (http://en.wikipedia.org/wiki/Naked_objects), might be a goal or perhaps that is another project?

//Jens

Could you put those features in separate pull request so that they can be easily reviewed/integrated individually? Definitively some interesting points you mention.

IMO a full naked objects implementation would be a bit too much for this ui project, but it would be a viable solution to provide some sort of integration with the MVC 4 nakedobjects project at codeplex.

Still, really curious about your improvements though.

Sure, I'm not sure that my Git-Fu is up to the task but I'll give it a try. A complicating fact is that in order to try all features out you need to build the nuget package. Maybe I can dump my source with all my changes in a repo of my own so you can se the changes?

Ok tried to dump what i have in https://github.com/jensj/twitter.bootstrap.mvc.extensions you'll find the features there.

Needs to be tidied up but I'm sure you'll get the concepts.

this is great stuff.. I just looked through your list and I am totally
aligned with all of it except the naked objects.. I have another project
that uses this UI project as the ui layer for a more opinionated mvc stack.
i will check out the code .

Eric Hexter

blog | http://Hex.LosTechies.com
info | http://www.linkedin.com/in/erichexter

On Mon, Dec 3, 2012 at 12:59 PM, jensj notifications@github.com wrote:

I've been playing with this project a bit and find it quite useful for
scaffolding basic CRUD for admin-purposes.

I have created a few generic components for things like:

  • paging using bootstrap paging
  • dropdowns for create/edit using valid choises provided in view data
  • search functionality for lists/paged lists
  • replacement of id values with clear text data from referenced
    objects in displays/lists
  • generic partials for actions on items in lists

Would you like things like this to be added to this project? If so I'd be
glad to post examples and pull requests.

By adding more of these things this project could be ending up in an Naked
Objects implementation (http://en.wikipedia.org/wiki/Naked_objects),
might be a goal or perhaps that is another project?

//Jens


Reply to this email directly or view it on GitHubhttps://github.com//issues/27.

Ok, so if I start with the search feature, do you (all) think that an attribute marking searchable properties would be a good way forward? Other options could be to define this in a separate class á la FluentValidation...

I guess I dont understand what you are thinking as far as what the ui would
look like to understand why you need to designate on the model if it is
included in the search. That would seem like server side implementation
detail.

Eric Hexter

blog | http://Hex.LosTechies.com
info | http://www.linkedin.com/in/erichexter

On Wed, Dec 5, 2012 at 4:09 PM, jensj notifications@github.com wrote:

Ok, so if I start with the search feature, do you (all) think that an
attribute marking searchable properties would be a good way forward? Other
options could be to define this in a separate class á la FluentValidation...


Reply to this email directly or view it on GitHubhttps://github.com//issues/27#issuecomment-11063030.

I wouldn't like it if twitter.bootstrap.mvc would require me to decorate my model objects with attributes, although I wouldn't mind it as an additional option. A good example would be mvc's validation, where you can do validation using attributes (data annotations [Required] etc), but you can also plug in your own validation framework (like FLuentValidation you mention).

In general, I think this project should fit in a variety of application stacks; it should be possible to use twitter.bootstrap.mvc in an active record project, but also in a cqrs style app. The requirements you put on your mvc model object play a large role. Attributes are part of the class, so they should not be required, but can be nice to have.

btw, Eric mentioned starting a sample project (#29 (comment)) which would be a great place to start adding you features.

The sample project would be great. One reason for that is that one can give examples on how to use this project in a good way.

Take paging for example, unless you want to rely on ViewData (which I personally not like for this) you need some kind of base class for paging as I have created in my own lab solution (https://github.com/jensj/twitter.bootstrap.mvc.extensions). In a sample solution one can get some hints on how to implement this in a way that works with a reference implementation of search functionality.

I think this UI project is not the right place for hosting a paging base class or DataAnnotations, but a sample project might be. The same goes for search functionality where you might want to define searchable properties.

Well, paging is a good example of something you'll at least want to partly delegate to your infrastructure. But at the same time, you'll need to define the PagedList concept in the bootstrap.mvc project. I solved this by defining a PagedList class in my web project and provide an extension method on IEnumerable that delegates to my persistence framework - RavenDB in my case, but this is were developers would want to plug in their own.

My implementation looks like this:

namespace MyProject.Infra.Paging
{
    public interface IPagedList : IEnumerable
    {
        int PageIndex { get; }
        int PageSize { get; }
        int TotalCount { get; }
        int TotalPages { get; }
        bool HasPreviousPage { get; }
        bool HasNextPage { get; }
    }

    public interface IPagedList<T> : IPagedList, IList<T>
    {
    }

    public class PagedList<T> : List<T>, IPagedList<T>
    {
        public PagedList(IEnumerable<T> source, int pageIndex, int pageSize) :
            this(source.GetPage(pageIndex, pageSize), pageIndex, pageSize, source.Count()) { }

        public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
        {
            this.TotalCount = totalCount;
            this.TotalPages = totalCount / pageSize;

            if (totalCount % pageSize > 0)
                TotalPages++;

            this.PageSize = pageSize;
            this.PageIndex = pageIndex;

            this.AddRange(source.ToList());
        }

        public int PageIndex { get; private set; }
        public int PageSize { get; private set; }
        public int TotalCount { get; private set; }
        public int TotalPages { get; private set; }

        public bool HasPreviousPage { get { return (PageIndex > 0); } }
        public bool HasNextPage { get { return (PageIndex + 1 < TotalPages); } }
    }
    // ...

I can imagine something similar being included in twitter.bootstrap.mvc; at least you'll need some concept of IPagedList to build the html paging controls of twitter bootstrap.

Now this has some issues (e.g the ienumerable is iterated twice) but it would work, even in the case someone wants to page a list with a gazillion items into pages of 10 items each.
But it does work out-of-the-box and easily allows for extending with "smart" paging extensions: paging methods that delegate to NHibernate, RavenDB or whatever.

In my app I use an extension method that delegates to RavenDB (for clarity, this should NOT be included in twitter.bootstrap.mvc):

    // cont.: raven extensions
    public static class PagingExtensions
    {
        public static IPagedList<T> ToPagedList<T>(this IRavenQueryable<T> query, int page, int pageSize)
        {
            RavenQueryStatistics stats;
            var q2 = query.Statistics(out stats)
                                .Skip((page - 1) * pageSize)
                                .Take(pageSize)
                                .ToList();

            var list = new PagedList<T>(
                            q2,
                            page - 1,
                            pageSize,
                            stats.TotalResults
                        );
            return list;
        }

        public static IPagedList<T> ToPagedList<T>(this IEnumerable<T> query, int page, int pageSize)
        {
            return new PagedList<T>(query, page - 1, pageSize);
        }

        public static IEnumerable<T> GetPage<T>(this IEnumerable<T> source, int pageIndex, int pageSize)
        {
            return source.Skip(pageIndex*pageSize).Take(pageSize);
        }
    }
}

I can imagine similar extension methods can be written in whatever persistence technology the developer wants to use. They might even be included as a sample of some kind, but twitter.bootstrap.mvc should obviously not take a dependency on a persistence framework of any kind.

Totally agree.

For me it makes sense that the base UI library provides a set of functionality, and whenever some kind of infrastructure needs to be implemented to support that functionality it can be supplied as interfaces leaving implementation to the user.

Bootstrap includes paging and therefore it makes sense that this library does too.

Nice implementation by the way, and as you say - it should work out of the box and still be extendable to suit the presistence mechanism is use.

I will get a sample project or if one of you want to add one, we can merge
in and modify the current source to work with a sample project in a way
that works better for us.

Eric Hexter

blog | http://Hex.LosTechies.com
info | http://www.linkedin.com/in/erichexter

On Thu, Dec 6, 2012 at 6:36 AM, jensj notifications@github.com wrote:

Totally agree.

For me it makes sense that the base UI library provides a set of
functionality, and whenever some kind of infrastructure needs to be
implemented to support that functionality it can be supplied as interfaces
leaving implementation to the user.

Bootstrap includes paging and therefore it makes sense that this library
does too.

Nice implementation by the way, and as you say - it should work out of the
box and still be extendable to suit the presistence mechanism is use.


Reply to this email directly or view it on GitHubhttps://github.com//issues/27#issuecomment-11083694.

It would be great if you could add one, Eric. I'm not really sure about the packaging step and what the most convenient directory structure would be.

Just giving this a bump as like @jensj I've been using this as a platform for building basic admin CRUD aspects, but it only gets us part of the way there and I'm not sure where you'd like to draw the line for responsibilities of the project.

Both the Rails and Django communities have a solution for this space, whereas it seems we do not. In particular, I'm fond of http://activeadmin.info/ both in the workflow and features for the admin user as well as the simplicity for the developer.

Both those stacks are much more opinionated vs. .Net MVC which makes it a somewhat more difficult problem to solve cleanly.

Anyway, I just figured I'd reach out as there's obviously a lot of overlap with this project at the needs of an 'admin' system.

http://activeadmin.info/ looks interesting and there definitely are some elements there that could be ported here. I'm thinking of the global navigation (already covered), the action items, the different index styles and sidebar items.

The action items are now rendered per entity/record (buttons on each line in the grid) and actions per entity-type (such as "create new") are only supported through scaffolding.

As Eric pointed out, the twitter.bootstrap.mvc project a.t.m. is scoped to support the UI only so stuff like filtering and user management is out-of-scope. That being said, twitter.bootstrap.mvc could very well be part of an ActiveAdmin .NET port, but I would not expect for all ActiveAdmin features to make it into twitter.bootstrap.mvc.

you hit on some great points here.. I think one of the things that has been
killing the asp.net mvc community is an opinionated framework that can get
work down in a simple way. It seems that most of the opinionated web
frameworks are so over the top with the old alt.net ideas.. that
asp.netmvc is not a clean enough implementation or that the opinions
are so geared
towards a cutting edge practice that it does not get adopted. I have some
strong opinions as well, but I think mine are more pragmatic. I see this
project sitting at the top of the stack, I personally have three variations
of architectures that I will put into an mvc application depending on the
complexity of the problem I am solving. I think all of these can use the
bootstrap package as part of the ui.

That being said, I see user management as one area that needs improvement.
With the new mvc 4 social logins, it gets more interesting as well. The
asp.net team is working on improvements to the membership system, it has
needed an overhaul for a long time, so we will see where that plays out.
once I can get this project stabilized in the next month, I will be making
a more opinionated web framework that uses this available as well. I would
expect that others could do the same.

Eric Hexter

blog | http://Hex.LosTechies.com
info | http://www.linkedin.com/in/erichexter

On Wed, Jan 2, 2013 at 1:31 AM, Marijn van der Zee <notifications@github.com

wrote:

http://activeadmin.info/ looks interesting and there definitely are some
elements there that could be ported here. I'm thinking of the global
navigation (already covered), the action items, the different index styles
and sidebar items.

The action items are now rendered per entity/record (buttons on each line
in the grid) and actions per entity-type (such as "create new") are only
supported through scaffolding.

As Eric pointed out, the twitter.bootstrap.mvc project a.t.m. is scoped to
support the UI only so stuff like filtering and user management is
out-of-scope. That being said, twitter.bootstrap.mvc could very well be part
of
an ActiveAdmin .NET port, but I would not expect for all those
features to make it into twitter.bootstrap.mvc.


Reply to this email directly or view it on GitHubhttps://github.com//issues/27#issuecomment-11801444.

@jensj I've added pull request #51 that introduces paging with html helper for easy use in razor. Feedback is appreciated. Also, there is a convenient way of testing the packages, see readme#contribute for details.

@serra - Looks nice, haven't had time to check out it action though.

@jensj - IMO it would be a good idea to close this general issue and instead open small, dedicated issues like we did with #58 and #51.

agreed

Eric Hexter

blog | http://Hex.LosTechies.com
info | http://www.linkedin.com/in/erichexter

On Wed, Jan 30, 2013 at 2:14 AM, Marijn van der Zee <
notifications@github.com> wrote:

@jensj https://github.com/jensj - IMO it would be a good idea to close
this general issue and instead open small, dedicated issues like we did
with #58 https://github.com/erichexter/twitter.bootstrap.mvc/issues/58and
#51 #51.


Reply to this email directly or view it on GitHubhttps://github.com//issues/27#issuecomment-12878687.

Sure, no problem for me. Where is the place to do general discussions about ideas implementation details etc. I'm mainly on twitter @JensJonsson and Google+.