To run djaoapp locally, you will need to install 3 types of dependencies
- Javascript dependencies (see package.json)
- Pure Python dependencies (see requirements.txt)
- Python bindings and native libraries (see requirements-native.txt and quirks for debugging version issues)
The css files are built through saasc.
To rebuild the css files run the following make command:
make build-assets
As it is inconvienient to edit/build/reload every time you make a change, the AssetView
class is used to detect changes and rebuild /static/cache/base.css
as necessary on page load. For that you need to make sure DEBUG
is True
and the --nostatic
flag is passed to the runserver command line.
DEBUG=1 python manage.py runserver --nostatic
So make your .sccs updates and reload the page!
The website is built as a Multi-Page Application (MPA). As much as possible the template filenames follow the URL on which the template is used. For example: you can find the template for /profile/{profile}/subscriptions/
in djaoapp/templates/saas/profile/subscriptions.html
. More details on the content of each page is available in the default theme documentation.
Django reads and re-compiles the template on page load.
So make your .html template updates and reload the page!
Because the site is using a Multi-Page Application (MPA) architecture, there are no complex business logic and/or dependency logic in the Javascript code. The order of the <script>
HTML elements in the templates is pretty straightforward.
Most developers will work with a very recent browser with the latest EcmaScript features available. So in DEBUG mode, all we really want to do is to be able to inclde the .js files through <script>
HTML elements in one of the base.html
template.
Because we want to be able to work when no Internet connection is available, we serve local copies of 3rd party vendor scripts in development mode. The static assets are served by Django so they must be found through the STATICFILES_FINDERS
settings. The following make target insures that.
make vendor-assets-prerequisites
Then make your .js updates and reload the page!
To support production mode (i.e. DEBUG=False
), we would like:
- 3rd party vendor scripts loaded through the official CDN whenever possible to take advantage of browser caching.
- Transpile and optimize the Vue components native to the website so they work on target browsers.
That is why we use a Universal Module Definition (UMD)] format as a wrapper and specific webpack plugins (Technically we only need to append to an exports
variable it is exists).
Typically npm, webpack and other Javascript tools will install and expect a node_modules directory in your source tree. That is just ugly, bloats your backups and really cramp your style when you are working with command line tools such as grep
. Furthermore we have .js files present in static directories of Django app installed in the virtual env site-packages
directory that must be imported.
The generate_webpack_paths
Django command creates a webpack-conf-paths.json
file that contains the same search path as set in settings.STATICFILES_FINDERS
(followed by VIRTUAL_ENV/lib/node_modules/
for vendor modules). That webpack-conf-paths.json file is then loaded in webpack.config.js
to set the modules search path for webpack.
To compile .js production asset files run the following make command:
make build-assets
Updating the Python code and debugging changes works as expected. You will notice that the website code base itself contains very little Python code itself - mostly to tie the major Django apps together.
- djaodjin-signup for authentication pages and APIs
- djaodjin-saas for subscription-based payment pages and APIs
- djaodjin-rules for role-based access control and HTTP request forwarding
- djaodjin-deployutils for encoding/decoding sessions
- djaodjin-extended-templates for live editing of theme templates
Whenever possible translated strings should be written in the HTML templates within {% trans %}{% endtrans %}
markers.
We initially generated translation units for the Vue components but it had many drawbacks:
- It required to load a djaoapp-i18n.js file at runtime.
- It required to re-bundle the assets to fix a typo.
- Translation strings were in two separate
.po
files (one for the Python/HTML templates and one for the Javascript).
Since then we made it a policy that there should not be any translation strings within the .js files. If it is necessary to pass translatable text to a component, do so through a component configuration variable and initialize that component with the default text value in the HTML template.
To add another language, generate a new translation unit with the following command:
python manage.py makemessages -l {locale_name}
Edit the generated djaoapp/locale/{locale_name}/LC_MESSAGES/django.po file with appropriate translations. Then compile the messages into a .mo
file.
python manage.py compilemessages
Run the the server using the following command, the browse http://localhost:8000/docs/api/
DEBUG=0 API_DEBUG=1 python manage.py runserver
The APIDocView
view will spit out warning and error messages whenever examples provided do not match the API definition.
When the API reference documentation looks reasonnably well, generate an OpenAPI schema.
make generateschema
Run the following command
make package-docker