Backbone.js page layouts & having model collection available globally - backbone.js

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"}
]);

Related

Is there a way to show images in a Wagtail Model Admin Record Listing page?

I have reviewed the question on Is there any way to show a field on a listing page in Wagtail admin? but my situation seems to similar but also different enough that that particular solution won't work for me. Instead of on the Page listing I wish to achieve a similar thing on the Model Admin listing and I would think this should be such a common requirement that I am picking that someone must have done this before I have attempted it.
I haven't really figured out how to even try anything to get started but what I have looked at is the modeladmin template tags under wagtail.contrib.modeladmin on GitHub but I am completely guessing.
Can anyone point me to which templates I need to modify and whether I need to modify any of the template tags and how to override anything I need to override?
There's no need to override templates for this - this is standard functionality in ModelAdmin. Adding extra fields to the listing is done by setting list_display on the ModelAdmin class:
class BookAdmin(ModelAdmin):
model = Book
list_display = ('title', 'author')
For displaying images, ModelAdmin provides ThumbnailMixin:
from wagtail.contrib.modeladmin.mixins import ThumbnailMixin
from wagtail.contrib.modeladmin.options import ModelAdmin
class BookAdmin(ThumbnailMixin, ModelAdmin):
model = Book
thumb_image_field_name = 'cover_image'
list_display = ('title', 'author', 'admin_thumb')
('admin_thumb' is a special-purpose field name provided by ThumbnailMixin, and should be used rather than the actual image field on your model - cover_image in this example.)

Template and model reuse in Wagtail

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

Independent views or different methods for a page?

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();

cakephp: abstract classes, factory, return objects

I would need an idea or two how I would do this in cakephp (using latest version)
I am building a web based game where you will be able to collect Items
Without a framework I would have an abstract base item class that every item would extend to
And when displaying for example a inventory i would factory all items the user currently have and then return a object for each item.
classes...
BaseItem
WeaponItem
HealingItem
etc..
How would I do this in cakephp? Would I go for a model for each item class ... and how would i factor to get the object? ...
Assuming you're using a database as the data store, presumably you will use a single table for all items the player can collect? If so, you probably want a single Model class.
It's possible to have an inheritance hierarchy for models in CakePHP if you want. But you can often achieve sharing of Model logic using a Behaviour.

cakePHP: how to combine two or more application views on one cakePHP layout page?

Using cakePHP my goal is to combine the index view of two or more controllers in one layout page.
Example:
I have controllers for: news, events, links.
I want to show the last five entries from each table in one layout page.
Also, when one of the links from the views is selected it should take the user to the respective view for that record.
I have read through the books section on views but don't see how making a view into an element would accomplish this.
What confuses me is how to combine from three separate controller/views into one layout?
Thanks
Create methods in your News, Event and Link models for fetching the last 5 records. Then in your controller either include the models in the Controller::uses property, or in the action use ClassRegistry::init() to get access to the model, e.g.
function my_action() {
$news = ClassRegistry::init('News')->getRecent();
$events = ClassRegistry::init('Event')->getRecent();
$links = ClassRegistry::init('Link')->getRecent();
$this->set(compact('news', 'events', 'links'));
}
You can then call these model methods from any controller action, keeping your application DRY.
In your my_action.ctp view, and indeed many other views, just render the elements e.g.
// my_action.ctp
<?php
echo $this->element('recent_news');
echo $this->element('recent_events');
echo $this->element('recent_links');
?>
Your elements can then just iterate over the $news (or whatever) variable displaying the items with links to the 'view' actions in their respective controllers.
Just because a controller matches a model, doesn't mean you can't use other models in it.
First I would say that views and controllers are not necessarily tied together -- Cake will implicitly add the view specified by the file heirarchy / naming convention, but this doesn't necessarily have to be the case. So try to think of the views as decoupled from the controller (which is one of the main purposes for using the MVC architecture).
Assuming your three views (A,B,C) are exactly how you want them copied, put them into an element (which is just a view file located in the special APP/views/elements/ directory). Now you can use them in either layouts or other views, just by making a call to $this->element( 'elementName', array( 'options' ) ).
Basically, just abstract the code you want to display into elements, then insert those elements into the desired layouts.
You can set up your controller to use the RequestHandler and then make your view elements capable of fetching their own data from separate controllers in your application.
This link explains it better than I can
http://bakery.cakephp.org/articles/view/creating-reusable-elements-with-requestaction
One thing to keep in mind is that the controller actions you are calling should account for caching their own data so you don't do unnecessary database queries.

Resources