Skip to content

Instantly share code, notes, and snippets.

@victor-enogwe
Last active October 27, 2021 05:13
Show Gist options
  • Select an option

  • Save victor-enogwe/8a04f733f1d0d26b77ede2848744bb04 to your computer and use it in GitHub Desktop.

Select an option

Save victor-enogwe/8a04f733f1d0d26b77ede2848744bb04 to your computer and use it in GitHub Desktop.
Angular SSR DJango

Angular SSR rendering for python Apps.

... Leave a question if you've got one.

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"YOUR_APP": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss",
"changeDetection": "OnPush"
}
},
"root": "",
"sourceRoot": "client",
"prefix": "YOUR_APP_PREFIX",
"architect": {
"serve-ssr": {
"builder": "./ssr/builders:ssr-dev-server",
"options": {
"browserTarget": "YOUR_APP",
"serverTarget": "YOUR_APP:server",
"host": "localhost",
"port": 8000,
"serverStartCommand": "python manage.py runserver"
},
"configurations": {
"production": {
"browserTarget": "YOUR_APP:production",
"serverTarget": "YOUR_APP:production"
}
}
}
}
}
}
}
import os
from django.template import Template
from django.template import TemplateDoesNotExist
from django.template.backends.django import DjangoTemplates, reraise
from django.template.context import make_context
from django.views.generic.base import TemplateView
from Naked.toolshed.shell import muterun_js
from config.settings import BASE_DIR
class AngularTemplate:
template_name: str = 'angular' # does nothing
def __init__(self, template: Template, backend: DjangoTemplates):
self.template = template
self.backend = backend
@property
def origin(self):
return self.template.origin
def html_render(self, request=None, context=None):
renderer = os.path.join(BASE_DIR, 'static/server/main.js')
js_render = muterun_js(
renderer, request.build_absolute_uri(request.path))
html = '{{nonce}} {0}'.format(
js_render.stdout.decode(encoding='UTF-8'))
template = Template(
html, self.origin, self.template_name, self.backend.engine)
return template.render(context)
def render_type(self, request: HttpRequest):
content_types = request.META.get('HTTP_ACCEPT').split(',')
extension = request.path.split('.')[-1]
return content_types + [extension]
def render(self, context=None, request=None):
autoescape = self.backend.engine.autoescape
context = make_context(context, request, autoescape=autoescape)
is_html = 'text/html' in self.render_type(request)
try:
return self.html_render(request, context) if is_html else None
except TemplateDoesNotExist as exc:
reraise(exc, self.backend)
class AngularTemplateEngine(DjangoTemplates):
html: str = None
def from_string(self, template_code):
return AngularTemplate(self.engine.from_string(template_code), self)
def get_template(self, template_name) -> TemplateView:
return self.from_string(template_name)
"..."
STATIC_PATH = os.path.join(BASE_DIR, 'static/browser') # see your angular application for more details
TEMPLATES = [
{
'BACKEND': 'config.templates.backends.AngularTemplateEngine',
'DIRS': [STATIC_PATH],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
],
},
},
]
import { CommonEngine, RenderOptions } from '@nguniversal/common/engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { resolve } from 'path';
import 'zone.js/node';
export * from '../client/main.server';
const { AppServerModule, LAZY_MODULE_MAP } = require('../client/main.server');
const [url] = process.argv.slice(2);
const documentFilePath = resolve(__dirname, '../browser/index.html');
const options: RenderOptions = {
bootstrap: AppServerModule,
url,
documentFilePath,
providers: [provideModuleMap(LAZY_MODULE_MAP)],
};
async function renderHtml(renderOptions: RenderOptions): Promise<boolean> {
const engine = new CommonEngine(AppServerModule);
return engine
.render(renderOptions)
.then((html) => process.stdout.write(html))
.catch((error) => process.stderr.write(error));
}
renderHtml(options).catch((error) => process.stderr.write(error));
from os import environ
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^.*', AngularView.as_view())
]
import os
from django.views.generic.base import TemplateView
class AngularView(TemplateView):
template_name = "angular"
def get_template_names(self):
return [self.template_name]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment