When nikola creates the page from this post it's going to copy over the javascript file ("get_started.js") and put it next to the HTML file for the post, which is why we can just put the file name in the script
tag and don't need a path. In order for nikola to find the original file to copy over we need to put it in a folder whose path looks like files/posts/<SLUG>/get_started.js
(starting from the root of the nikola repository). You can probably change it but this is the way it works by default.
The <SLUG>
has to be the slugified name for the post (for nikola this is set in the slug
metadata at the top of the post). In this case I used the much too long slug p5-js-with-org-mode-and-nikola
so the path to the javascript file is files/posts/p5-js-with-org-mode-and-nikola/get_started.js
.
We need to know this for two reasons:
- One is that it's where you have to put the file or it won't get copied over when nikola builds the site (you will have to make the folder if you didn't do it previously).
- The other is that I want to show the javascript itself in this post so we'll put in an org-mode
include
directive with the path to the file.
The thing that I tend to stumble over when embedding other files into an org-mode post is that the path for the include
directive is relative to the location of the org-mode post, not the root of the nikola repository. Since the org-mode file for this post is in a sub-folder named posts
, our path needs to go up one directory first, then back down, like this:
#+include: ../files/posts/p5-js-with-org-mode-and-nikola/get_started.js src js
Wherever you put the include directive in the post is where org-mode will insert the contents of the file. The arguments after the path tell org that it's a source block (and not, say, an example) and that it's in javascript so org will apply the right syntax highlighting to it, like so:
function get_started(p5js){
const WHITE = 255;
const COLOR = p5js.color(0, 0, 255);
let diameter;
p5js.setup = function() {
let canvas = p5js.createCanvas(0.8 * p5js.windowWidth, 200);
p5js.background(WHITE);
p5js.strokeWeight(3);
p5js.stroke(COLOR);
p5js.fill(WHITE);
}; // setup
p5js.mousePressed = function() {
p5js.background(COLOR);
}; // mouse_pressed
p5js.mouseReleased = function() {
p5js.background(WHITE);
}; // mouse_released
p5js.draw = function() {
/* Draw circles that change diameter based on mouse speed */
/* and color based on if mouse-pressed (or not pressed) */
if (p5js.mouseIsPressed) {
p5js.fill(COLOR);
p5js.stroke(WHITE);
} else {
p5js.fill(WHITE);
p5js.stroke(COLOR);
}
diameter = p5js.pow(p5js.dist(p5js.pmouseX, p5js.pmouseY,
p5js.mouseX, p5js.mouseY), 1.5);
p5js.ellipse(p5js.mouseX, p5js.mouseY, diameter, diameter);
}
}; // get started
new p5(get_started, "get-started");
You don't need to actually show the javascript, and I would normally do it by putting the code in the post itself and then tangling it out, the way I do it for the next sketch, but this is how I did it originally and so this is for the future me that might want to but will probably forget how to do it.