Skip to content
Emmanuelle Delescolle edited this page Nov 21, 2015 · 2 revisions

Welcome to the Toga Web wiki.

What is Toga Web?

This application is an attempt at finding a new way for Django Generic Class-Based views to embrace the future of the web and be:

  • Not just about displaying a list or a form but several of those things a the same time, think like your github profile page for example:
    • a detailview (you picture and info)
    • a tablist
    • several listviews (popular repos, repos contributed to, activity chart, etc...)
  • Being able to integrate with more modern tools and framework like javascript frontend frameworks or native mobile applications.

Where does it come from?

This project is originally a merge of two existing ideas from @nanuxbe and @freakboy3742 during Django Under The Hood 2015. During the sprints, @jrief and @Psykopear also joined the project.

Original goal of the project

This project aims at creating a simple way to describe a complex interface in Django. It should be possible to feed this simple interface specification to different standalone frontends.

EmberJS and Toga were the first candidates as 2 of the project members heavily use these frameworks/tools. AngularJS and ReactJS were also mentioned as they are currently among the most popular frontend JS frameworks.

To stay true to Django, it should also be possible to use this new project to create pure HTML by using this project.

Decisions taken during the DUTH sprint

  • Given the current capabilities of Django REST Framework and the fact there are talks about making it either part of django.contrib or at least making it the "official Django REST tool", DRF will be used to interact with the database backend for all implementations (even pure for HTML rendering, using a DRF renderer similar to the one use by DRF to render its web interface)
  • After several hours of reflection we came up with the ideal syntax to aim for when declaring a View (independent of its targeted renderer).
  • Although classes for an AngularJS renderer will be different than the ones for an HTML render This is what we came up with for a pure HTML rendered, they should inherit from the same base classes and have a relatively similar syntax.
  • as CBV's are used in Django using as_view(), it seemed fit to use as_component() to create ephemeral instances of the components during the rendering process. A POC of this concept as been validated by @jrief during the sprints
  • the list_display syntax is a reference to Django Admin's list_display and has been validated as being used by @nanuxbe on another (EmberJS-centric) project
  • in the spirit of Django the sytax that we have agreed upon is to stay close to te one used in Django Forms.

Here is an the syntax we are aiming for (in this example, we are recreating GitHub profile page):

class ProfilePage(Page):
    user_details = UserInfo()
    tabs = TabCollection()
    contributions = ContributionList()

    class Meta:
        template_name="profile.html"


class UserInfo(DetailComponent, TemplateView):

    class Meta:
        endpoint = 'api-user-info'
        verb = 'GET'
        template_name = 'userinfo.html'

        list_display = [
            {
                'field': 'picture',
                'widget': 'widget-img',
            }, {
                'field': 'full_name'
            }, {
                'field': 'username'
            }
        ]

    def get_endpoint_full_url(self, **kwargs):
        kwargs['username'] = self.request.kwargs['username']
        return super(UserInfo, self).get_endpoint_full_url(**kwargs)

class TabCollection(ComponentCollection, TemplateView):
    contributions = ContributionsTab()
    repositories = RepositoriesTab()
    activity = ActivityTab()

    class Meta:
        template_name = 'tabs.html'


class TabComponent(ComponentCollection, TemplateView):

    class Meta:
        template_name = 'tab.html'


class ContributionsTab(TabComponent):
    
    popular_repo = PopularRepoList()
    contributed_to = ContributedToList()
    contributions = ConttributionsList()

    class Meta:
        template_name = 'component-tab.html'


class PopularRepoList(ListComponent):

    default_action = Action('details', 'repo', params=['slug'])

    class Meta:
        endpoint = 'popular_repo'
        list_display = [
            {
                'field': 'is_fork',
                'widget': 'widget-fork',
            }, {
                'field': 'path'
            }, {
                'field': 'stars',
                'widget': 'widget-star',
            }
        ]