Answer the question
In order to leave comments, you need to log in
How to smartly specify a static resource inside a template engine?
I'm building a static website
using Gulp .
The site is still static and in the future it is planned to switch to dynamics. How to refer to images, audio, etc. inside the template engine. from one file, so that when you change it, you don’t get into the template code, but fix it there.
Looking towards JSON to specify everything
"static" : {
"images" : {
"wallpaper": {
src : "https://example.com/images/img.png",
alt : "Image PNG"
},
"graphicClip" : {
src : "https://example.com/images/png.png"
}
},
},
"Text" : {
English : "English string",
Russian : "Russian string"
}
}
<img src={{static.images.wallpaper.src}} alt={{static.images.wallpaper.alt}}
<p>{{static.text.English}}</p>
<p>{{static.text.Russian}}</p>
Answer the question
In order to leave comments, you need to log in
Good afternoon! In my projects, I just use such a "handicraft" approach, dividing it into two stages:
1) loading global constants into the nunjucks engine before compiling pages (stored in json);
2) adding a filter for issuing locales (also stored in json, but in a separate folder).
Roughly speaking, these are two ways to implement,
the first is unloading the global constant in nunjucks into the context ( gulp-nunjucks-render , render api );
the second is the use of an entity separate from nunjucks (in my case, an i18next instance without a backend ), in which there is a synchronous process of issuing data on demand through a custom nunjucks filter.
Now, having spent about 8-9 months with such an assembly, I can say that there are a lot of conventions, bugs and performance problems during assembly. And in general, it does not fit into the framework of at least some global concept for organizing code (which will simply complicate support in the future). Probably a better solution is to set up some ready-made static site generator than to write your own build. But if you're wondering where to start, here's the structure and code:
├── datasets
│ └── meta.json
├── locales
│ ├── en
│ │ └── translation.json
│ └── ru
├── tasks
...
└── gulpfile.js
# Это упрощенная структура,
# но если вам будет что-то непонятно, я напишу подробнее.
import gulp from 'gulp';
import fs from 'fs';
import path from 'path';
import i18next from 'i18next';
import config from '../gulpfile.config';
import engine from 'gulp-nunjucks-render';
import minify from 'gulp-htmlmin';
import Backend from 'i18next-sync-fs-backend';
import rename from 'gulp-rename';
i18next.use(Backend).init({
debug: true,
fallbackLng: ['en'],
initImmediate: false,
backend: {
loadPath: config.paths.locales + '/{{lng}}/{{ns}}.json' // локали собираются по названиям из папки locales
},
ns: ['translation'],
defaultNS: 'translation'
});
export function html(done) {
const envHooks = [
env => env.addFilter('__', function(key, ns) { // фильтр на поиск и выдачу информации по ключу в i18next
if(!i18next.exists(key)) return 0;
return i18next.t(key);
}),
]
const data = fs.readdirSync( config.paths.datasets ).reduce( (acc, filename) => {
return { ...acc, [ path.basename( filename, '.json') ] : require('../' + config.paths.datasets + '/' + filename) };
}, {});
data.get = function(name) {
return this[name];
}
const [ def ] = i18next.options.fallbackLng;
const rec = (arr) => {
const [lng, ...rest] = arr;
return i18next.changeLanguage(lng, (err) => {
if(err) throw new Error(err);
return gulp.src(config.paths.pages)
.pipe(engine({
data: {
datasets: data,
},
path: ['src/pages/templates'],
manageEnv: function(env) {
return envHooks.forEach(fn => fn(env));
},
}))
.pipe(minify({ collapseWhitespace: true }))
.pipe(rename(function(path) {
path.basename = lng === def ? path.basename : lng + '.' + path.basename;
}))
.pipe(gulp.dest(config.server.dest))
.on('end', () => {
return rest.length ? rec(rest) : done();
});
});
}
rec(['ru', 'en']); // если язык дефолтный, то страницы компилируются обычным образом, если нет - у них будет префикс с названием языка
return;
};
<!--
datasets/features.json
[
{
"name" : "independent",
"_descr" : "features.indep.descr"
},
{
"name" : "secure",
"_descr" : "features.secure.descr",
},
]
-->
{% set features = datasets.get('features') %}
<ul class="page-home__features">
{% for f in features %}
<li>
{{ feature.make(f) }}
</li>
{% endfor %}
</ul>
<!--
locales/en/translation.json
"pages" : {
"home" : {
"headings" : {
"qualities": "a perfect solution for projects"
}
}
}
-->
<code lang="html">
<h2 class="text-center font-weight-bold mb-4 mb-lg-6">
{{ 'pages.home.headings.qualities' | __ }}
<!-- фильтр зарегистрирован под названием __ -->
</h2>
</code>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question