{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# AngularJS feat. requireJS (as dependency to Jupyter Notebook)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# standard IPython modules for working with frontend output\n", "from IPython.display import SVG, Javascript, HTML, display\n", "\n", "# Gotta pimp the package that makes things easier\n", "import simplejson as json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A basic partial template file with AngularJS directives" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cat: templates/input_template.ng: No such file or directory\n" ] } ], "source": [ "# We can just read the file with Jupyter's shell commands \"!\"\n", "!cat templates/input_template.ng" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## We can load the dependencies files by reading into IPython.display.javascript" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cat: js/deps.js: No such file or directory\n" ] } ], "source": [ "# Dependency js, although it can't be loaded via Javascript() the file for display\n", "!cat js/deps.js" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Prepare a python dictionary with some values\n", "`kernel.execute(\"print(python_dict)\")` will be executed by javascript" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/plain": [ "'{\"input\": \"templates/input_template.ng\", \"input_id\": \"content\"}'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "python_dict = {\"input\": \"templates/input_template.ng\", \"input_id\": \"content\"}\n", "json.dumps(python_dict)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "text/html": [ "

We just create a container to hold the content of our angular template\n", "
\n", "(%%html is magic to define html to be rendered)

\n", "

It'll be empty until we run the below...or until the autosave runs

\n", "Note the html ID=\"container\"\n", "
\n", "
Not Loaded...
\n", "
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "

We just create a container to hold the content of our angular template\n", "
\n", "(%%html is magic to define html to be rendered)

\n", "

It'll be empty until we run the below...or until the autosave runs

\n", "Note the html ID=\"container\"\n", "
\n", "
Not Loaded...
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Now with some %%javascript magic, read the notes as we step through the levels" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [ { "data": { "application/javascript": [ "//require needs to be configed with the dependencies\n", "require.config({\n", " paths: {\n", " velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n", " interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n", " angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n", " },\n", " shim: {\n", " 'angular': {\n", " exports: 'angular'\n", " }\n", " }\n", "});\n", "//top level function will be fed into our callback\n", "function handle_output(data){\n", " //data is the object passed to the callback from the kernel execution\n", " console.log(data)\n", " //to get the print statement from the text, we get the content key\n", " //then we convert it via JSON parse\n", " //now you can arbitrarily transfer a JSON string using the python_dict variable\n", " var python_dict = JSON.parse(data.content.text.trim())\n", " console.log(python_dict)\n", " //Utilized requireJS built into the frontend of Jupyter Notebook\n", " //Pass in the modular dependencies you wish to use\n", " //For this example, we created our own and passed it into the config obj\n", " // paths: {\n", " // velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n", " // interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n", " // angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n", " // }\n", " //jquery is already available\n", " //find all the modules here\n", " console.log(require.s.contexts._.defined)\n", " //now we get to the requirejs -> angular\n", " require(['angular','jquery'], function(a,$) {\n", " console.log(a)\n", " //a and $ are now our variables for the modules\n", " //we using an ajax call to the jupyter notebook server\n", " //here we get the variable passed in, and us the input to locate the file\n", " $.ajax({url: \"http://localhost:8888/files/\"+python_dict.input,\n", " //once the file is retrieved, we have a callback, so we're one step deeper\n", " success: function(result) {\n", " //now we locate the ID=\"contaner\" which is defined above %%html magic\n", " //pass out file result\n", " console.log('SUCCESS')\n", " $(\"#container\").html(result);\n", " //now select the element we just loaded as the result (we pull from the python_dict)\n", " var el = document.getElementById(python_dict.input_id);\n", " //We have to be prepared to teardown and restart our controller\n", " //if the injector() is available, then angular as been bootstrapped\n", " //so destroy the scope and tree to reboot.\n", " if(a.element(el).injector()){\n", " a.element(el).injector().get('$rootScope').$destroy()\n", " }\n", " //Now we get to the actual module, the a here was conntected to the angular module\n", " //myApp is only connected to the bootstrap\n", " //at this point, all angular stuff is fair game, and you can define your modules and controllers\n", " //nothing special for this hello world.\n", " a.module('myApp', [])\n", " .controller('MyController', ['$scope', function ($scope) {\n", " $scope.greeting = 'Hello';\n", " $scope.name = 'Darling!!!';\n", " }]);\n", " //we bootstrap (\"INITIALIZE\") the application so that we can easily keep control\n", " angular.element(document).ready(function() {\n", " angular.bootstrap(el, ['myApp']);\n", " });\n", " }\n", " });\n", " });\n", " \n", "}\n", "//callbacks is an object whose so special, it appears to only have been documented in\n", "//the source code, as no only google found me a link.\n", "//callbacks.iopub.output is used to get the data from execute\n", "var callbacks = {\n", " iopub : {\n", " output : handle_output,\n", " }\n", "}\n", "//execute anything you want; if a string value is returned\n", "//you can print it out and pass it to the callbacks \n", "//(or do other things, no idea, it's poorly documented online \n", "//(read the source F12->static/notebook/js/services/kernels/kernel.js)\n", "//kernel.js/Kernel.prototype.execute \n", "var kernel = IPython.notebook.kernel;\n", "kernel.execute(\"print(json.dumps(python_dict))\",callbacks)\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%javascript\n", "//require needs to be configed with the dependencies\n", "require.config({\n", " paths: {\n", " velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n", " interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n", " angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n", " },\n", " shim: {\n", " 'angular': {\n", " exports: 'angular'\n", " }\n", " }\n", "});\n", "//top level function will be fed into our callback\n", "function handle_output(data){\n", " //data is the object passed to the callback from the kernel execution\n", " console.log(data)\n", " //to get the print statement from the text, we get the content key\n", " //then we convert it via JSON parse\n", " //now you can arbitrarily transfer a JSON string using the python_dict variable\n", " var python_dict = JSON.parse(data.content.text.trim())\n", " console.log(python_dict)\n", " //Utilized requireJS built into the frontend of Jupyter Notebook\n", " //Pass in the modular dependencies you wish to use\n", " //For this example, we created our own and passed it into the config obj\n", " // paths: {\n", " // velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n", " // interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n", " // angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n", " // }\n", " //jquery is already available\n", " //find all the modules here\n", " console.log(require.s.contexts._.defined)\n", " //now we get to the requirejs -> angular\n", " require(['angular','jquery'], function(a,$) {\n", " console.log(a)\n", " //a and $ are now our variables for the modules\n", " //we using an ajax call to the jupyter notebook server\n", " //here we get the variable passed in, and us the input to locate the file\n", " $.ajax({url: \"http://localhost:8888/files/\"+python_dict.input,\n", " //once the file is retrieved, we have a callback, so we're one step deeper\n", " success: function(result) {\n", " //now we locate the ID=\"contaner\" which is defined above %%html magic\n", " //pass out file result\n", " console.log('SUCCESS')\n", " $(\"#container\").html(result);\n", " //now select the element we just loaded as the result (we pull from the python_dict)\n", " var el = document.getElementById(python_dict.input_id);\n", " //We have to be prepared to teardown and restart our controller\n", " //if the injector() is available, then angular as been bootstrapped\n", " //so destroy the scope and tree to reboot.\n", " if(a.element(el).injector()){\n", " a.element(el).injector().get('$rootScope').$destroy()\n", " }\n", " //Now we get to the actual module, the a here was conntected to the angular module\n", " //myApp is only connected to the bootstrap\n", " //at this point, all angular stuff is fair game, and you can define your modules and controllers\n", " //nothing special for this hello world.\n", " a.module('myApp', [])\n", " .controller('MyController', ['$scope', function ($scope) {\n", " $scope.greeting = 'Hello';\n", " $scope.name = 'Darling!!!';\n", " }]);\n", " //we bootstrap (\"INITIALIZE\") the application so that we can easily keep control\n", " angular.element(document).ready(function() {\n", " angular.bootstrap(el, ['myApp']);\n", " });\n", " }\n", " });\n", " });\n", " \n", "}\n", "//callbacks is an object whose so special, it appears to only have been documented in\n", "//the source code, as no only google found me a link.\n", "//callbacks.iopub.output is used to get the data from execute\n", "var callbacks = {\n", " iopub : {\n", " output : handle_output,\n", " }\n", "}\n", "//execute anything you want; if a string value is returned\n", "//you can print it out and pass it to the callbacks \n", "//(or do other things, no idea, it's poorly documented online \n", "//(read the source F12->static/notebook/js/services/kernels/kernel.js)\n", "//kernel.js/Kernel.prototype.execute \n", "var kernel = IPython.notebook.kernel;\n", "kernel.execute(\"print(json.dumps(python_dict))\",callbacks)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [conda env:bjorn36]", "language": "python", "name": "conda-env-bjorn36-py" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.7" }, "widgets": { "state": {}, "version": "1.1.1" } }, "nbformat": 4, "nbformat_minor": 4 }