For a small project using 11ty I want to pull in a package to the node_modules folder and access some of the data in a .json file within that package.
I'm doing something similar in another project using fractal where I'm using (pseudo code):
module.exports = {
context: {
colors: require('path/to/tokens/color-tokens.json')
}
};
I've tried adding this in a couple of places and I've got 11ty finding the file (it errors if I get the path wrong) but I seem to not be able to access it in nunjucks with something likes this (pseudo code):
{% for item in colors.properties %}
// code to pull in the relevant values.
{% endear %}
Am what I'm wanting doable (and I've just got it wrong somewhere)? Or do I need to set up a little gulp task to copy the .json file to the relevant _data folder and rename it to the .md file that would be using it?
I haven't tested this but assuming your _data lives at src/_data you could create a file in _data called colors.js and pull in the data there.
const colors = require('../../node_modules/PATH_TO_JSON');
module.exports = colors;
{% for item in colors %}
{{ item }}
{% endfor %}
Do you have a public repo available?
Thanks @chrisssycollins!
I've tried this and it does appear to find the file correctly but I'm not getting any data out of it. The project is not public just yet.
So I have:
in the .json file in node_modules:
{
"properties": [
{
"name": "green",
"value": "#009f4d"
},
{
"name": "blue",
"value": "#307fe2"
},
]
}
In colors.js which is in src_data/styles/ I have:
'use strict';
const path = require('path');
const colors = require(path.join(process.cwd(), 'node_modules/@org/design-tokens/dist/json/colors.json'));
module.exports = colors;
and in the .md in site/styles/ I have:
{% for item in colors.properties %}
<p><span>{{ item.name }}</span>: {{ item.value }}</p>
{% else %}
<p>It's not working</p>
{% endfor %}
The .json I'm using is being used in another project that's similar to this but with Fractal and it's working fine - so I'm doing something wrong - but cannot still work it out.
I'll persevere - thanks for the heads up on .js file in the src/_data folder :)
(edited after seeing @Ryuno-Ki's comment where I had some bad nunjucks)
const colors = require(path.join(process.cwd(), 'node_modules/@org/design-tokens/dist/json/colors.json'));
In Node.js, everything under node_modules is considered a package.
That is, this should work:
const colors = require('@org/design-tokens/dist/json/colors.json'));
If not, I'd use __dirname instead of process.cwd.
Have you checked the value of colors, i.e. is the JSON loaded in the JS file?
Oh, and <p><span>{{ item.name }}</span>: {{ item.colour }}</p> won't work. In the JSON, it is .value not .colour.
Oh, and
<p><span>{{ item.name }}</span>: {{ item.colour }}</p>won't work. In the JSON, it is.valuenot.colour.
Ah, this is me just quickly typing things out to be brief. As mentioned I have this working perfectly with a similar project using Fractal. The .js I'm using there to get the .json is:
With colors.config.js having:
'use strict';
const path = require('path');
module.exports = {
context: {
colors: require(path.join(process.cwd(), '@org/design-tokens/dist/json/colors.json'))
}
};
and then having nunjucks pulling in the data in the colors.nunj.
Which is where I'm scratching my head (of course, knowing 11ty and Fractal are two different pieces of software)
@Ryuno-Ki
Have you checked the value of colors, i.e. is the JSON loaded in the JS file?
I don't know how I would do this :(
'use strict';
const path = require('path');
const colors = require(path.join(process.cwd(), 'node_modules/@org/design-tokens/dist/json/colors.json'));
console.log("Colors");
console.log(colors);
module.exports = colors;
Would be a quickhack ;-)
Thanks @Ryuno-Ki <3
I got this (reduced as it's long) in my terminal:
Colors
{ properties:
[ { type: 'color',
category: 'color',
name: 'vfColorGreen',
value: '#009f4d',
meta: [Object] },
{ type: 'color',
category: 'color',
name: 'vfColorGreenDarkest',
value: '#115740',
meta: [Object] }
]
}
What is the file path to the colors.js file?
Eleventy loads data from the /_data folder with the filename as the namespace. If you've got it under src/_data/styles as it looks like above, you should be able to access the contents in nunjucks by adding the styles subdirectory to the namespace:
{% for item in styles.colors.properties %}
<p><span>{{ item.name }}</span>: {{ item.value }}</p>
{% else %}
<p>It's not working</p>
{% endfor %}
Thanks @robb0wen
I quickly duplicated the .json file from node_modules into _data/styles and changed:
{% for item in colors.properties %}
to
{% for item in styles.colors.properties %}
and it works great - so now I'm trying to work out why it's not doing this when the .json file is deep within the tunnels of node_modules.
I quickly duplicated the .json file from node_modules into _data/styles
That's going to be my last-chance saloon if what I'm wanting is just not going to work with 11ty. Several gulp tasks copying from node_modules and renaming the .json filename to match the .md. 馃槶
Just to clarify, When you had the node_modules require path set in src/_data/styles/colors.js, and added the console log to that file, you got an output of the data object in the terminal, but couldn't access the data in your template using the styles.colors namespace?
@robb0wen Yep, similar to:
Colors
{ properties:
[ { type: 'color',
category: 'color',
name: 'vfColorGreen',
value: '#009f4d',
meta: [Object] },
{ type: 'color',
category: 'color',
name: 'vfColorGreenDarkest',
value: '#115740',
meta: [Object] }
]
}
Ok, so that suggests that it is loading the data. If you log typeof colors is it coming back as object?
@robb0wen Yes, when including
console.log(typeof colors); I get object in the terminal
I can't see why, if you can see the correct data and type in the terminal, it isn't working in the template.
I just created a quick comparison test to pull a package.json file from within a node_modules folder. I've used the same approach as above, using path.join and a data file in a subfolder.
src/_data/styles/test.js
const path = require('path');
const pkg = require(path.join(process.cwd(), 'node_modules/@11ty/eleventy/package.json'));
module.exports = pkg;
then the nunjucks:
{% for item in styles.test.keywords %}
<p>{{ item }}</p>
{% endfor %}
This works for me, it might be worth testing on your setup too
Thanks @robb0wen
Your example made to try and swap styles.colors.properties to styles.colour.properties to match the filenames - it works as expected.
Thanks everyone for taking time to get me through a spelling error 馃槶
鉂わ笍 鉂わ笍 鉂わ笍 鉂わ笍 鉂わ笍
Thank you everyone!!
Most helpful comment
Thanks @robb0wen
Your example made to try and swap
styles.colors.propertiestostyles.colour.propertiesto match the filenames - it works as expected.Thanks everyone for taking time to get me through a spelling error 馃槶
鉂わ笍 鉂わ笍 鉂わ笍 鉂わ笍 鉂わ笍