Skip to content

Instantly share code, notes, and snippets.

@VovanR
Last active August 29, 2015 14:03
Show Gist options
  • Save VovanR/7716e8183592bdeec2df to your computer and use it in GitHub Desktop.
Save VovanR/7716e8183592bdeec2df to your computer and use it in GitHub Desktop.
Django AMD with Require.js

Django AMD with Require.js

App options

apps/foo/templates/foo/index.html

{% load staticfiles %}

...

{# jQuery is global for third party modules #}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src=\'{% static "vendor/jquery/dist/jquery.min.js" %}\'><\/script>')</script>

{# Third party JavaScript files #}
{% block scripts %}
{% endblock scripts %}

{# AMD JavaScript below #}
{% compress js %}
<script src="{% static 'vendor/requirejs/require.js' %}"></script>
{% endcompress %}

<script>
var lang = '{{ LANGUAGE_CODE|default:"en-GB" }}';
window.MainOptions = {
    uiLang: lang === 'en' ? 'en-GB' : lang === 'zh-cn' ? 'zh-CN' : lang,
    ajaxLinks: {
        login: "{% url 'login' %}",
    },
};

{# JavaScript Apps settings #}
{% block define_scripts %}
{% endblock define_scripts %}

{% if debug %}
    require(['{% static "js/common.js" %}'], function () {
        require(['{% static "js/default-page.js" %}']);
{% else %}
    require(['{% static "built/common.js" %}'], function () {
        require(['{% static "built/default-page.js" %}']);
{% endif %}
    {# Apps are there #}
    {% block require_scripts %}
    {% endblock require_scripts %}
});
</script>

Common config

static/js/common.js

/**
 * @author <name> [<emailAddress>]
 */

// Tests uses another path
if (!requirejs.config.baseUrl) {
    requirejs.config.baseUrl = '/static/js';
}

requirejs.config({
    baseUrl: requirejs.config.baseUrl,
    paths: {
        // vendor
        jqueryui: '../vendor/jquery-ui/ui',
        underscore: '../vendor/underscore/underscore',

        // apps paths
        foo: '../foo/js',
    },
});

define('./common', [], function () {  });

define('jquery', [], function () { return window.jQuery; });

define('jquery.ui.widget', ['jqueryui/widget'], function (w) { return w; });

Common config for JS tests

static/js/common-test.js

/**
 * @author <name> [<emailAddress>]
 */

requirejs.config({
    baseUrl: requirejs.config.baseUrl,
    paths: {
        // vendor
        jqueryui: '../../bower_components/vendor/jquery-ui/ui',
        underscore: '../../bower_components/vendor/underscore/underscore',

        // apps paths
        foo: '../../apps/foo/static/foo/js',
    },
});

define('jquery', [], function () { return window.jQuery; });

define('jquery.ui.widget', ['jqueryui/widget'], function (w) { return w; });

App Build

static/js/app.build.js

{
    appDir: '../js',
    baseUrl: '.',
    dir: '../built',
    optimize: 'uglify2',
    optimizeCss: 'none',
    paths: {
        jqueryui: '../../bower_components/vendor/jquery-ui/ui',
        underscore: '../../bower_components/vendor/underscore/underscore',

        // apps paths
        foo: '../../apps/foo/static/fop/js'
    },
    shim: {
    },
    modules: [
        {
            name: './common',
            include: [
                'underscore'
            ]
        },
        {
            name: './foo-page',
            include: ['foo/app/foo-app'],
            exclude: ['./common']
        }
    ]
}

App page

static/js/foo-page.js

/**
 * @author <name> [<emailAddress>]
 */

require(['./common'], function (common) {
    require(['foo/app/foo-app'], function (App) {

        var app;
        var o = window.AppOptions;

        app = new App(o);

    });
});

App

apps/foo/static/foo/js/app/foo-app.js

/**
 * @author <name> [<emailAddress>]
 */

define([
    'jquery',
    'underscore',
    'foo/modules/module-name',
], function (
    $,
    _,
    ModuleName
) {

    var App;
    var defaults = {
        foo: 'foo',
    };

    /**
     * Application name
     *
     * @param {Object} o Options
     * @param {String} [o.foo='foo']
     */
    App = function (o) {
        this.o = o || {};
        _.defaults(this.o, defaults);

        this._moduleName = null;

        this._init();
    };

    App.prototype = {
        /**
         * Initialize
         *
         * @private
         */
        _init: function () {
            console.info('App init');

            this._initModuleName();

            this._bindControls();
        },

        /**
         * Bindings
         *
         * @private
         */
        _bindControls: function () {
            var _this = this; // Save context
        },

        /**
         * @private
         */
        _initModuleName: function () {
            this._moduleName = new ModuleName({
                bar: 'baz',
            });
        },
    };

    return App;

});

Module

apps/foo/static/foo/js/modules/module-name.js

/**
 * @author <name> [<emailAddress>]
 */

define([
    'jquery',
    'underscore',

    // nothing returns
    'jqueryui/datepicker',
    'jqueryui/i18n/datepicker-' +
        (
            window.MainOptions ?
            (window.MainOptions.uiLang ? window.MainOptions.uiLang : 'en-GB') :
            'en-GB'
        ),
], function (
    $,
    _
) {

    var ModuleName;
    var defaults = {
        bar: 'bar',
    };

    /**
     * Module name
     *
     * @param {Object} o Options
     * @param {String} [o.bar='bar']
     */
    ModuleName = function (o) {
        this.o = o || {};
        _.defaults(this.o, defaults);

        this._init();
    };

    ModuleName.prototype = {
        /**
         * Initialize
         *
         * @private
         */
        _init: function () {
            console.info('ModuleName init');

            $('#bar-datepicker').datepicker();

            this._bindControls();
        },

        /**
         * Bindings
         *
         * @private
         */
        _bindControls: function () {
            var _this = this; // Save context
        },
    };

    return ModuleName;

});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment