Профиль пользователя заблокирован в режиме deactivate сроком с 4 июня 2019 г. и навсегда по причине: нарушение п. 2.5. условий пользовательского Соглашения
  • Как учиться учиться?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Подозреваю, это индивидуальная особенность, с которой ничего не поделать. По крайней мере у меня с концентрацией именно так - минимум полчаса на включение и в лучшем случае час на выключение, а в сконцентрированном состоянии стеклянные глаза и полная потеря коммуникативных способностей.
    Ответ написан
  • Как по уму указать статичный ресурс внутри шаблонизатора?

    @ned4ded
    Верстка, Фронтенд
    Добрый день! В своих проектах как раз использую такой "кустарный" подход, разделяя его на два этапа:
    1) подгрузка глобальных констант в движок nunjucks до компиляции страниц (хранятся в json);
    2) добавление фильтра на выдачу локалей (тоже хранятся в json, но в отдельной папке).

    Грубо говоря, это два способа реализации,
    первый - выгрузка глобальной константы в nunjucks в контекст (gulp-nunjucks-render, render api );
    второй - это использование отдельной от nunjucks сущности (в моем случае экземпляр i18next без бекенда), в которой происходит синхронный процесс выдачи данных по запросу через кастомный фильтр nunjucks.

    Сейчас, проведя с такой сборкой уже около 8-9 месяцев, могу сказать, что там много условностей, багов и проблем с производительностью при сборке. И в целом она не умещается в рамки хоть какой-нибудь глобальной концепции по организации кода (что просто усложнит поддержку в будущем). Наверное, более правильное решение - это настроить какой-то готовый генератор статических сайтов, чем писать свою собственную сборку. Но если вам интересно, с чего начать, то структура и код:

    ├── datasets
    │   └── meta.json
    ├── locales
    │   ├── en
    │   │   └── translation.json
    │   └── ru
    ├── tasks
    ...
    └── gulpfile.js
    
    # Это упрощенная структура, 
    # но если вам будет что-то непонятно, я напишу подробнее.


    код html таска на сборку страниц
    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;
    };


    В коде демонстрируется сразу 2 подхода. В темплейтах вызывается по-разному:
    1)
    <!--
    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>


    2)
    <!--
     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>
    Ответ написан