I have to build a pretty complex application using Backbone Marionette. The user interface has to handle multiple users with different roles. For example the 'admin' user will see the complete menu whereas the 'guest' user will access a subset of the same menu. Moreover some views will be accessible to all the users but the functions inside them (add, edit, delete) need to be profiled on the different roles.
I am not sure about the right approach to use in order to solve this issue. I could have different templates for the different roles but in this case plenty of code will be duplicated inside them. Is there any best practice (or maybe some example) to sort my problem out using Marionette?
Thanks in advance,
Fabrizio
I would keep a mypermissions object and then write logic in the itemview to handle the different cases. You can make a CSS class called "hide" that is set to
display:none
Then you just add that class
This could be done without changing the template.
Here's an example in Coffeescript (not tested or anything)
AuthView = Backbone.Marionette.ItemView.extend
template: '#auth-template'
onRender: ->
#checkpermissions()
checkpermissions: ->
if (mypermissions.isUser)
$(".delete").addClass 'hide'
$(".add").addClass 'hide'
elseif (mypermissions.isAdmin)
$(".delete").removeClass 'hide'
$(".add").removeClass 'hide'
Related
I am building a fairly basic Wagtail site and have run into an issue regarding the reuse of models and templates.
Say my site has two kinds of entries:
blog posts and
events.
Both pages look the same and share many model fields (e.g., author, category, intro, etc.). However, there are some model fields that only make sense for the event entry type (e.g., event_date, event_venue).
What would be the ideal way of creating templates and models for this use-case without repeating myself in the code?
Right now, both blog and event entries use the same HTML template and the same model. However, when the user creates a blog post in the Wagtail admin, he or she has to "ignore" the event-specific fields (which may become even more in the future).
Do I have to create two separate template files and two separate models despite both blogs and events being 95% the same code? What would be the correct way to solve this in Wagtail?
If you want to maintain it the way it is, contained within one model and template, you could create separate model admins for each pseudo-type (Blogs and Events), and override the queryset function to make each separate modeladmin only show the ones you're looking for, and then edit the panels that are shown on create/edit/delete.
class EventAdmin(ModelAdmin):
...
panels = [
FieldPanel('your_field'),
...
]
def get_queryset(self, request):
qs = super().get_queryset(request)
events = qs.filter(your_field__isnull=False)
return events
More information at https://docs.wagtail.io/en/stable/reference/contrib/modeladmin/index.html
Sorry if my question is silly but I'm new to DNN/2sxc, I've spent the whole day trying to figure this with no success..
I have two instances of the same app, one in the home page and the other on its own page, each one must have its own view template (I use Razor).
My problem is I cannot figure a way to make the two apps read the same data, so every add/edit/remove/re-sort in one of them will be reflected to the other, currently each app has its own data and therefore they are unusable in my case.
I've tried to use a 'EntityTypeFilter' inside a 'Data Query' and use it in both views (as in the News-Simple demo video), it worked and gave me all the items in the two views, but another two problems come with this solution:
1- now I'm unable to use the toolbar to (add/remove/reorder,.. etc) any of the items , as you can see in this image, which is a show-stopper for me,
note: this is the toolbar I use:
#foreach(var item in AsDynamic(Data["Default"]))
{
...
#Edit.Toolbar(target: item, actions: "new,edit,replace,remove,moveup,movedown,instance-list")
2- the 'Content Demo Item' is also visible in the list, but it is not that important since I can delete it and use one of the real data items as a demo item.
I appreciate any kind of help.
Thank you.
So the first thing you should know is the difference when using content-items as data (to query, etc.) and when using it as assigned-items (where each module-instance has a subset of items). Here's the blog that should help you understand the difference: http://2sxc.org/en/blog/post/12-differences-when-templating-data-instead-of-content
So when you want the "manually and easily control the exact items displayed, their ordering etc." you want to use the "content-assigned-to-instance" which also gives you the simple add, delete buttons, as these don't really delete anything, but just remove the assignment from the module-instance.
Now your case is a bit special, in that you want to re-use the exact same set in another module-instance. There are a few ways you can do this:
Same View
if it's exactly the same view etc. just duplicate the module using DNN-features (the add-existing-module-to-another page)
different view
if it's a different view (maybe more compact, etc.) you again have multiple options. The first is to mirror / duplicate using the dnn-feature, and just put an if-im-on-this-page-then-show-differently or inject another CSS. That's probably the easiest without any dev-know-how.
The harder, but possibly nicer way, is to actually to use a new template, and tell it to retrieve the items in the way they are configured in the other module - let's say module 1 is the original, module 2 has a different template wanting to access the items of module 1 in exactly the same order as given in 1. They way to do this is simple, but requires a few lines of C# code in Module 2.
You need to create a new ModuleDataSource (https://2sxc.org/en/Docs/Feature/feature/4542) object and tell it that it's from Module 1. If you've never done this, it's basically that your code can create a query just like the visual designer, but you have more control - see the wiki https://github.com/2sic/2sxc/wiki/DotNet-DataSources-All. The Module-Data-Source in the visual-query-designer doesn't allow you to "switch" modules (a advanced setting we may add in the future) but the object has a ModuleId property which you can set before accessing the data, making it "switch" to that Module. here's the Pseudo code in your Module#2 razor...
var otherModData = CreateSource<ModuleDataSource>();
otherModData.ModuleId = 1;
foreach(var itm in AsDynamic(otherModData["Default"])) {
...
}
That should do it :)
I have an application that the unique thing that uses Backbone is a navigator that highlights where the user are. I mean, it's a "breadcrumb" to guide him to locate himself.
But now, I'm implementing internationalization and I need to identify which language the user is navigating in – and I would to do that with Backbone as well.
Until now, my view is this:
var breadcrumbView = new BreadcrumbView({
scope: '#{#scope}'
});
Then I ask: it's better to create another view just for the internationalization fashion or the right thing to do is aggregate this two resources into a HomeView? E.g.
var home = new HomeView;
home.Breadcrumb.create('#{#scope}');
home.Internationalization.create();
I found the right solution. Let's go?
Understanding the real problem
The meaning of "internationalization" in my question refers to highlighting which language the user is using. Let's suppose that the "current" language is en-US, then we highlight it in the menu of languages.
Extracting the solution
Firstly, I searched on Wikipedia the follow explanation about views:
A view is told by the controller all the information it needs for generating an output representation to the user. It can also provide generic mechanisms to inform the controller of user input.
Source
Secondly, I know that internationalization and breadcrumbs are components of my view. Of my view. You see? These two "features" aren't the view itselves – they're just components that compose it.
Implementing the solution
Based on the knowledge we acquired, is simple to say that internationalization and breadcrumbs should to be methods of my HomeView.
Translating this into code, this is the right thing to do:
var home = new HomeView;
home.Breadcrumb.create('#{#scope}');
home.Internationalization.create();
i've the following hierarchy structure : Group -> Family -> products -> Product details.
each node is retrieve through an $http service.
i would like the user to be able to drill down until the final product details and i would also like no reloads when the user hits the back button as parents never changes.
i've succeeded to build the first part using routes and it works pefectly but now each time i want to go back the controller of the parent view (last view) is reloaded and i don't know how to avoid this reloading.
i am thinking of changing my way of doing it by having only 1 view (while 4 before) and manage the drill down through a directive, do you think it could be considered as a good practice ? how would you implement this ?
You could check out AngularUI Router, since one of its main feature is the ability to nest states & views.
Have a look at the UI-Router Demo, source code here.
I'm working on a simple Backbone.js app for practice - a people quote database. (Person has many Quotes and Comments)
Questions
I would like to have two layouts.
One is a standard two column layout, with one column as a sidebar and the other as the content area. (I would like to embed the view into that column, and keep the sidebar static.)
The other would be a simple one-column layout for authentication purposes (I want to add authentication as well, since this is a practice project). A simple page with a login form. Obviously, this layout would only be used for one view.
How can I do this? Is there a plug-in that will make this possible/easy? (Essentially, is there an equivalent to the Rails layout system?)
On that sidebar, I would like to have a list of Person model objects, so a list of all Person objects must be available on each page. In Rails, I would accomplish this with a simple before_filter in the ApplicationController.
What is the best way to accomplish this?
I worked on a project which also required a similar layout structure. We had a rails app with two backbone instances on the frontend. To get our layout we used jQuery-UI-Layout. This will allow you to create multiple 'panels' which represent your sidebar and column. Then you can simply render your views into each panel, and they will be very nicely separated.
when you create your quotes and comments views, you can pass them the people collection so they have access to the person model objects.
so...
Say you have a 'main_view', this main view will initialize your jQuery ui layout.
$(this.el).layout({options})
where options will set the sizing on your Quotes and Comments panels. Then you create your views and pass them the 'people' collection, which is a collection of your 'person' models.
new App.Views.QuotePanelView({
el: $(this.el).find('#quote_panel'),
collection: people
})
Here people is a collection of people. And the same goes for the comments panel.
var people = new People([
{"name" : "James Cameron"},
{"name" : "Bat Man"},
{"name" : "Cool Guy"}
]);