Dynamic assets prefix in Ember-CLI build-generated index.html - ember-cli

I asked this question earlier today, and then deleted it, cause I thought I found an answer that was too obvious to post on here. Basically, how do you change something like this in dist/index.html:
<script src="assets/my.js"></script>
to something like this:
<script src="http://my.assets.com/assets/my.js"></script>
I instantly realized that I can just set the src in app/index.html and it will appear in dist/index.html.
But now I'm realizing that there's a better, if slightly more complex, solution - one that allows different settings in different environments. So I am re-adding the question and posting the answer below.

The solution requires ember-cli-inline-content
Brocfile.js:
global require, module, process;
...
if (process.env.EMBER_ENV === 'development') {
app.options.inlineContent = {
assetPrefix: {
content: 'http://my.assets.com/'
}
};
}
index.html:
<script src="{{content-for 'assetPrefix'}}assets/my.js"></script>

Related

GitHub: How to get `utteranc.es` to work for website discussion

My website https://friendly.github.io/HistDataVis/ wants to use the seemingly light weight and useful discussion feature offered by the https://github.com/utterance app.
I believe I have installed it correctly in my repo, https://github.com/friendly/HistDataVis, but it does not appear on the site when built.
I'm stumped on how to determine what the problem is, or how to correct it. Can anyone help?
For reference, here is my setup:
The website is built in R Studio, using distill in rmarkdown.
I created utterances.html with the standard JS code recommended.
<script>
document.addEventListener("DOMContentLoaded", function () {
if (!/posts/.test(location.pathname)) {
return;
}
var script = document.createElement("script");
script.src = "https://utteranc.es/client.js";
script.setAttribute("repo", "friendly/HistDataVis");
script.setAttribute("issue-term", "og:title");
script.setAttribute("crossorigin", "anonymous");
script.setAttribute("label", "comments ??");
/* wait for article to load, append script to article element */
var observer = new MutationObserver(function (mutations, observer) {
var article = document.querySelector("d-article");
if (article) {
observer.disconnect();
/* HACK: article scroll */
article.setAttribute("style", "overflow-y: hidden");
article.appendChild(script);
}
});
observer.observe(document.body, { childList: true });
});
</script>
In one Rmd file, I use in_header to insert this into the generated HTML file:
---
title: "Discussion"
date: "`r Sys.Date()`"
output:
distill::distill_article:
toc: true
includes:
in_header: utterances.html
---
Also used this in my _site.yml file to apply to all Rmd files on the site.
On my GitHub account, I installed utterances under GitHub apps, and gave it repository access to the repo for this site.
Edit2
Following the solution suggested by #laymonage, I fixed the script. I now get the Comments section on my web page, but get an error, "utterances not installed" when I try to use it. Yet, utterances is installed, as I just checked.
This part of your code:
if (!/posts/.test(location.pathname)) {
return;
}
Prevents the rest of the script to load because it's always true.
The condition checks whether the value of location.pathname passes the regular expression test string posts and negates it (!). That means the condition is true if the location.pathname (the path name of the current URL, e.g. /HistDataVis/ for https://friendly.github.io/HistDataVis/) does not contain posts anywhere in the string. None of the pages on your website has posts in the pathname, so the script will end there.
It should work if you change /posts/ to /HistDataVis or just remove the if block altogether.
Alternatively, you can also try giscus, a similar project that uses GitHub Discussions instead of Issues. Someone already made a guide on how to use it with Distill. Disclaimer: I'm the developer of giscus.

hyperHTML seemingly fails to call (attach?) onload events

I'm attempting to dynamically conditionally load additional JavaScript while using hyperHTML. I've narrowed the failure to the onload event.
Here's an attempt at a minimal, complete, and verifiable example:
class ScriptLoader extends hyperHTML.Component {
onload(event) {
notie.alert({ text: "notie loaded" });
}
render() {
return this.html`
<script
src=https://unpkg.com/notie
type=text/javascript
async=false
onload=${this}
/>
`;
}
}
hyperHTML.bind(document.body)`
<h2>onload test (notie)</h2>
${new ScriptLoader}
`;
<script src="https://unpkg.com/hyperhtml#2.4.0/min.js"></script>
As you can see notie.alert is never called, even though the script is inserted correctly.
This some process works correctly using vanilla JS with addEventListener('load', and appendChild(.
Update this was an issue with Firefox and Web (Safari) considering death nodes scripts injected via innerHTML, even if through a template and after imported.
That means the issue was not with the onload per-se, rather the fact no network request was ever triggered so that onload would never happen indeed.
As you can verify now in the Code Pen eaxmple, which uses your exact same snippet I rewrite in part to make SO happy about me linking Code Pen, both Firefox and Safari, as well as Chrome and Edge should work just fine.
hyperHTML.bind(document.body)`
<h2>onload test (notie)</h2>
${new ScriptLoader}
`;
I am keeping part of the old edit just to make you, or any other reader, aware of a little caveat that JSX affectionate might overuse.
There is one thing you should be careful with: hyperHTML does not parse HTML and <script/> is not valid HTML.
You are risking to find nodes where you shouldn't if you don't close non-void tags regularly, and this is beyond hyperHTML capabilities, unfortunately how HTML works in general.
<p/><b>unexpected</b>
I understand for this demo case you had to do that or the parse would complain with a closing script in the page but remember, you can always do this instead, when necessary:
`<script><\x2fscript>`

Default layout for ember-cli, instead of "UnrecognizedURLError

I have something like this:
{{topbar-nav}}
{{outlet}}
I have a lot of pages, where I want to render just the top-bar, and nothing else. Normally, I have to create a lot of routes, that would basically do nothing (rendering emptiness), and I don't want to pollute router like this. Is it possible to somehow handle this situation? For example a default route like:
this.default_route("default");
Well, I found it myself.
this.route('default_page', { path: '/*wildcard' });
Important part is
{ path: '/*wildcard' }

(How) can I use System.import in babel along with require.js?

I'm playing a little bit with the new ES6 functionalities and Babel. I'm successfully using the modules export/import functionalities by means of require.js (transpiling into AMD), but the experimental module loader doesn't want to work. Here is my code and configurations:
extract of front-app/tst.js
import {tstimp as functocall} from "front-app/tstimp.js";
...
/**
* LOADING MODULES DYNAMICALLY
*/
System.import('front-app/tst_dyn_mod')
.then(some_module => {
console('using the module!');
some_module.sayHello();
})
.catch(error => {
console.log('error!');
console.log(error);
});
My .babelrc looks like this:
{
"presets": ["es2015", "react"],
"plugins": ["transform-es2015-modules-amd"]
}
and the scripts I import are these ones, in that order:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script data-main="front-app/tst" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.8/require.min.js"></script>
<script src="node_modules/es6-module-loader/dist/es6-module-loader.js"></script>
</head>
<body></body>
</html>
Unfortunately what I get is the following error by using firefox:
error! tst.js:695:9
Error: a is undefined
Error loading http://localhost/es6r1/front-app/tst_dyn_mod
what's that a? Am I missing something? Keep in mind my code is transpiled into AMD, but System is supposed to stay there in the transpiled code (and it IS there). The polyfill should do the dirty job, right?
I successfully get the thing working on Babel 6 with a slighlty different config (babel-node cli & thus commonjs) thanks to this plugin: https://www.npmjs.com/package/babel-plugin-system-import (npm install babel-plugin-system-import-transformer). Here's a excerpt of my .babelrc:
…
"plugins": [
"system-import-transformer",
{
"modules": "common"
}
]
…
Setting amd instead of common like indicated in the documentation should do the trick for you.
Only limitation of this tiny plugin, you should get a plain string module name like System.import("plainString") and not a computed one (nor string concatenation with +, nor new ES6 template literal and neither variable name). It seemds linked to that line of code.
I will try to PR a fix on that limitation if I can.
Just an update on this, https://github.com/thgreasi/babel-plugin-system-import-transformer has support for non string parameters. Just make sure not to use the updated alias package.

IPython/Jupyter Installing Extensions

I'm having troubles installing extensions in IPython. The problem is that i can't get the extensions load automatically, i have followed the instructions in the github page but it just doesn't work. According the the homepage i need to modify the custom.js file by adding some lines. I want to install the codefolding, hide_input_all and runtools extensions. This is how my custom.js file looks:
// activate extensions only after Notebook is initialized
require(["base/js/events"], function (events) {
$([IPython.events]).on("app_initialized.NotebookApp", function () {
/* load your extension here */
IPython.load_extensions('usability/codefolding/codefolding')
IPython.load_extensions('usability/runtools/runtools')
require(['/static/custom/hide_input_all.js'])
});
});
The extensions work well if i call them manually, for example, if i type
%%javascript
IPython.load_extensions('usability/runtools/runtools/main');
the runtools appear and works perfectly, but i want the extensions to be loaded automatically and not to have to call them manually every time. Could someone tell me where is my mistake?
There's been a little change to the syntax. Nowadays, $ might not be defined by the time your custom.js loads, so instead of something like
$([IPython.events]).on("app_initialized.NotebookApp", function () {
IPython.load_extensions("whatever");
});
you should do something like
require(['base/js/namespace', 'base/js/events'], function(IPython, events) {
events.on('app_initialized.NotebookApp', function(){
IPython.load_extensions("whatever");
})
});
with the appropriate changes to braces and parentheses. For me, the former will work more often than not, but certainly not always; it fails maybe ~1/3 of the time.
If that doesn't do it for you, open up Developer Tools (or whatever is relevant for your browser) and look at the javascript console for errors. That'll help figure out what's going wrong.