Grails application context in javascript library - grails

Is it possible to access
grails.app.context
from within a javascript library? --That is, not javascript inserted in a GSP file.
I have som javascripts that are context dependent, why I need to be able to access this from javascript.
I include the javascript in my gsp-files with:
<r:require modules="myModule" />

You can pass it to Javascript as global JS variable, put this inside <head> tag:
<g:javascript>
window.appContext = '${request.contextPath}';
</g:javascript>
and use it anywhere from plain javascript, like:
$.ajax({
url: appContext + '/hello/world'
})

Related

How to add option in <redoc>?

I want to add some additional option to my ReDoc. For current implementation I am using json file that is generated from Swagger, and this is added in html page. Example how this is done:
<body>
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json'></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc#next/bundles/redoc.standalone.js"> </script>
</body>
I use this as referent documentation: https://github.com/Rebilly/ReDoc
How can I add option object in tag and not use ReDoc object? And how can I use vendor extension e.g. x-logo?
In documentation this is set via json file, but my json file is auto generate from Swagger.
You just place the options after the spec-url in the redoc tag like this:
<body>
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json' YOUR_OPTIONS_HERE></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc#next/bundles/redoc.standalone.js"> </script>
</body>
in this example on ReDoc repository you can verify it (line 22 at this moment):
https://github.com/Rebilly/ReDoc/blob/master/config/docker/index.tpl.html#L22
Important:
Remember to "kebab-casing the ReDoc options", as an example if your options are:
hideDownloadButton noAutoAuth disableSearch
YOUR_OPTIONS_HERE
should be (after kebab-casing them):
hide-download-button no-auto-auth disable-search
Your body with those options becomes like this:
<body>
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json' hide-download-button no-auto-auth disable-search></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc#next/bundles/redoc.standalone.js"> </script>
</body>
Hope it will be usefull to you.
ReDoc has advanced initialization via Redoc.init so you can download the spec manually and add some postprocessing (e.g. add an x-logo).
You can pass ReDoc options as the second argument to Redoc.init:
<body>
<div id="redoc"></div>
<script src="https://cdn.jsdelivr.net/npm/redoc#next/bundles/redoc.standalone.js"> </script>
<script>
fetch('http://petstore.swagger.io/v2/swagger.json')
.then(res => res.json())
.then(spec => {
spec.info['x-logo'] = { url: "link/to/image.png" };
Redoc.init(spec, {
// options go here (e.g. pathInMiddlePanel)
}, document.getElementById('redoc'));
});
</body>
NOTE: This requires Fetch API to be available in browsers so it won't work in IE11.
You can place your options next to spec-url.
Be sure that the version of Redoc you are using, have options you want to use, you can check it by going to the specific version. github.com/Redocly/redoc/tree/vx.x.x.
As a side note features lazy-rendering in available till v1.22.3.
https://github.com/Redocly/redoc#redoc-options-object
You can use all of the following options with standalone version on tag by kebab-casing them, e.g. scrollYOffset becomes scroll-y-offset and expandResponses becomes expand-responses.

How to embed Swagger UI into a webpage?

How to embed Swagger UI into a webpage? Basically I want an API endpoint test environment to embed into my webpage.
The answer depends on whether you have a plain web page you edit directly, or use a framework like Node.js or React. For simplicity, I'll assume the former.
Download (or clone) the Swagger UI repository. You'll need the following files from the dist folder:
swagger-ui.css
swagger-ui-bundle.js
swagger-ui-standalone-preset.js
In the <head> section of your web page, add:
<link rel="stylesheet" type="text/css" href="swagger-ui.css">
Inside the <body>, add:
<div id="swagger-ui"></div>
<script src="swagger-ui-bundle.js"></script>
<script src="swagger-ui-standalone-preset.js"></script>
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "https://yourserver.com/path/to/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
})
window.ui = ui
}
</script>
<div id="swagger-ui"></div> is the DOM node inside which Swagger UI will be rendered. The SwaggerUIBundle constructor initializes Swagger UI. This is where you specify your spec URL and other parameters.

How to use html templates in electron framework?

I need to build a cross platform app with multiple windows. So I would like to know how to use html templates in electron.
Based on a similar question and what I've seen, there's no built in html template language in Electron, which is actually great because it allows you to use any other template language.
I'm currently playing with ejs in Electron.
Below is my index.ejs template file:
<html lang="en">
<head>
<title>The Index Page</title>
</head>
<body>
<h1>Welcome, this is the Index page.</h1>
<% if (user) { %>
<h3>Hello there <%= user.name %></h3>
<% } %>
</body>
</html>
And below is a section of my main.js file where the above template is rendered and loaded onto the BrowserWindow. Note that I've left out most of the boilerplate code:
const ejs = require('ejs');
//... Other code
let win = new BrowserWindow({width: 800, height: 600});
//... Other code
// send the data and options to the ejs template
let data = {user: {name: "Jeff"}};
let options = {root: __dirname};
ejs.renderFile('index.ejs', data, options, function (err, str) {
if (err) {
console.log(err);
}
// Load the rendered HTML to the BrowserWindow.
win.loadURL('data:text/html;charset=utf-8,' + encodeURI(str));
});
I'll give some credit to this gist for helping me find the data:text/html;charset=utf-8 part of the url that can be used to load dynamic content.
UPDATE
I'm actually not using this anymore. It's faster to just load the default html and use the native DOM methods. The Electron Quickstart program shows how to do this nicely.
Another option is to do the templating during your build. Here is a simple example using gulp to add nonces to the CSP meta tag and the inline script.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-<%= scriptNonce %>';">
<title>Basic Electron App</title>
</head>
<body>
<div id="app"></div>
<script type="application/javascript" nonce=<%= scriptNonce %>>
require('./index.js');
</script>
</body>
</html>
and in gulfile.js add the following to what you already have and make sure this task is included in your pipeline. You can also just update your current html task with the code below.
const template = require('gulp-template');
const uuidv4 = require('uuid/v4');
gulp.task('copy-html', () => {
// Create nonces during the build and pass them to the template for use with inline scripts and styles
const nonceData = {
scriptNonce: new Buffer(uuidv4()).toString('base64'),
styleNonce: new Buffer(uuidv4()).toString('base64')
};
return gulp.src('src/*.html')
.pipe(template(nonceData))
.pipe(gulp.dest('dist/'));
});
This is a very stripped down example. I have a more complete example at https://github.com/NFabrizio/data-entry-electron-app if anyone is interested, though there is still one warning when running the application because one of the packages I am using pulls in react-beautiful-dnd, which adds inline styles but does not currently accept nonces.

Typescript AMD and AngularJs - Failed to instantiate module

I'm unsing TypeScript AMD (RequireJs) and AngularJs.
I want to use AMD for my typescript code and not for the rest: jquery, angular, bootstrap, ...
For thirdparty js I'm using MVC bundling and I want to continue this way.
This is my thirdparty bundle config:
bundles.Add(new ScriptBundle("~/bundles/thirdparty").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js",
"~/Scripts/require.js",
"~/Scripts/angular.js",
"~/Scripts/angular-route.js"
));
My _Layout.cshtml is something like:
<!DOCTYPE html>
<html ng-app="PafBase">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
#Scripts.Render("~/bundles/thirdparty")
<script>
require.config({
baseUrl: 'typescript/'
});
require(['module/BaseApplication']);
</script>
</head>
<body>
#RenderBody()
</body>
BaseApplication.ts is something like:
var app: ng.IModule = angular.module('PafBase', ['ngRoute']); // Breakpoint here ****
app.config(['$routeProvider', ($routeProvider) => { ... }]);
When run the application I get this javascript error:
[$injector:modulerr] Failed to instantiate module PafBase due to:
Error: [$injector:nomod] Module 'PafBase' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
If I continue the execution I can see that BaseApplication.ts is executed after the angular error.
I think it can be due to angular scan the DOM after ready and found <html ng-app="PafBase"> then search "PafBase" module and not find it due to requireJs don't load BaseApplication.ts before angular scan the DOM.
How to do angular scan the dom after my code is executed?
You can manually bootstrap Angular instead of specifying ng-app="PafBase". Take a look at the docs here: https://docs.angularjs.org/guide/bootstrap
Basically you just need to remove ng-app from your html and add this to your JS
angular.element(document).ready(function() {
angular.bootstrap(document, ['PafBase']);
});

how to use dust partial template files (.tl files)

I have few questions on partials and overriding templates.
For that i used the following folder structure.
projectRoot
dust-core-0.6.0.min.js
jquery.js
test.html
partial.tl
main_without_override.tl
The content of partial.tl:
{+greeting} Hola {/greeting}
{+world} World {/world}
The content of main_without_override.tl:
{>partial/}
The content of test.html:
<!DOCTYPE html>
<html>
<head>
<script src="dust-core-0.6.0.min.js" type="text/javascript"></script>
<script src="jq.js" type="text/javascript"></script>
</head>
<body>
</body>
<script>
$.get('main_without_override.tl', function(){
console.log(arguments);
})
</script>
</html>
In the index.html when i try to get the main_without_override.tl its saying 404. But im sure that the file is there. The path that firebug is showing is correct.But browser says 404.
I want to know
How to get this main_without_override.tl
Apply templating for main_without_override.tl and render in the browser.
I searched in google most of the examples give only the syntax. Can somebody help me in rendering the main_without_override.tl template.
In order to compile templates on the client (which is probably not a really good idea), you need to include dust-full instead of dust-core. This is because dust-core does not include the Dust compiler.
The reason that compiling templates on the client is probably not a good idea is that Dust compiles to JavaScript and as #monshi mentioned, you can compile the templates and then serve them as JavaScript. It is possible to get .tl files through AJAX if you include dust-full, but it is a better idea to compile that template beforehand and then make a dynamic request for that .js file when you need.
You can include your dust template as a JavaScript file by using <script> tag, but you need to compile it first, which is explained here
Then add following templates (scripts) to test.html:
<script type="text/javascript" src="partial.js"></script>
<script type="text/javascript" src="main_without_override.js"></script>
And in you JavaScript render the template by dust.render method:
dust.render('main_without_override', your_json_object, function(err, out){
your_dom_element.innerHTML = out;
});
Related question:
how to use dustjs-linkedin as client side templating?

Resources