how to combine angular2 with jinja2 templates and flask how to combine angular2 with jinja2 templates and flask flask flask

how to combine angular2 with jinja2 templates and flask


I had the same problem and here is how I solved it;

Step 1

With a directory structure as follows:

+- MyAppName
+-- ServerApp
+--- //...flask files here
+-- ClientApp
+--- node-modules
+--- app
+--- //...more node+angular application files

I exposed the ClientApp folder in my flask application at the URL .../client-app/... using the following code:

from flask import Flask, send_from_directoryimport osBASE_URL = os.path.abspath(os.path.dirname(__file__))CLIENT_APP_FOLDER = os.path.join(BASE_URL, "ClientApp")# This is required by zone.js as it need to access the# "main.js" file in the "ClientApp\app" folder which it# does by accessing "<your-site-path>/app/main.js"@app.route('/app/<path:filename>')def client_app_app_folder(filename):    return send_from_directory(os.path.join(CLIENT_APP_FOLDER, "app"), filename)# Custom static data@app.route('/client-app/<path:filename>')def client_app_folder(filename):    return send_from_directory(CLIENT_APP_FOLDER, filename)

Step 2

Head over to your index.html file (I placed mine at ServerApp\templates\index.html so that I could simply do render_template('index.html')) and make it look something like this:

<html>  <head>    <title>Angular 2 QuickStart</title>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <link rel="stylesheet" href="client-app/assets/css/style.css">    <!-- 1. Load libraries -->     <!-- Polyfill(s) for older browsers -->    <script src="client-app/node_modules/es6-shim/es6-shim.min.js"></script>    <script src="client-app/node_modules/zone.js/dist/zone.js"></script>    <script src="client-app/node_modules/reflect-metadata/Reflect.js"></script>    <script src="client-app/node_modules/systemjs/dist/system.src.js"></script>    <!-- 2. Configure SystemJS -->    <script src="client-app/systemjs.config.js"></script>    <script src=""></script>    <script>      System.import('app').catch(function(err){ console.error(err); });    </script>  </head>  <!-- 3. Display the application -->  <body>    <my-app>Loading...</my-app>  </body></html>

the 'client-app' prepended to the paths is the route I chose to expose my client_app_folder() function at

Step 3

Configure your client application's package finder to use the set route ('client-app/...' in this case). I use system.js and therefore I made my systemjs.config.js file look like this:

(function(global) {  // map tells the System loader where to look for things  var map = {    'app':                        'client-app/app', // 'dist',    'rxjs':                       'client-app/node_modules/rxjs',    'angular2-in-memory-web-api': 'client-app/node_modules/angular2-in-memory-web-api',    '@angular':                   'client-app/node_modules/@angular'  };  // packages tells the System loader how to load when no filename and/or no extension  var packages = {    'app':                        { main: 'main.js',  defaultExtension: 'js' },    'rxjs':                       { defaultExtension: 'js' },    'angular2-in-memory-web-api': { defaultExtension: 'js' },  };  var packageNames = [    '@angular/common',    '@angular/compiler',    '@angular/core',    '@angular/http',    '@angular/platform-browser',    '@angular/platform-browser-dynamic',    '@angular/router',    '@angular/router-deprecated',    '@angular/testing',    '@angular/upgrade',  ];  // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }  packageNames.forEach(function(pkgName) {    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };  });  var config = {    map: map,    packages: packages  }  // filterSystemConfig - index.html's chance to modify config before we register it.  if (global.filterSystemConfig) { global.filterSystemConfig(config); }  System.config(config);})(this);

I only modified the map variable

Godspeed!


When looking for the answer to this same question I was reminded about changing the interpolation characters in angular 1. Could find where two do that for angular 2, but it was simple enough to change on the jinja2 side. Set the jinja2 environment options characters however you want with this:

JINJA_ENV = jinja2.Environment(  loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),  extensions=['jinja2.ext.autoescape'],  block_start_string= '{[%',  block_end_string='%]}',  variable_start_string='{[',  variable_end_string=']}',  comment_start_string='{#',  comment_end_string='#}',  autoescape=True)

Hopefully I am using compatible strings here, guess I will find out!(see http://jinja.pocoo.org/docs/dev/api/ environment options)