UNPKG

twig

Version:

JS port of the Twig templating language.

118 lines (100 loc) 3.92 kB
// ## twig.path.js // // This file handles path parsing module.exports = function (Twig) { 'use strict'; /** * Namespace for path handling. */ Twig.path = {}; /** * @param {Twig.Template} template * @param {string} path */ Twig.path.expandNamespace = function (namespaces, path) { const namespaceIdentifiers = Object.keys(namespaces); const pattern = new RegExp(`^(?:@(${namespaceIdentifiers.join('|')})/|(${namespaceIdentifiers.join('|')})::)`); return path.replace(pattern, (wholeMatch, atNamespace, colonNamespace) => { const namespaceIdentifier = (atNamespace === undefined ? colonNamespace : atNamespace); return `${namespaces[namespaceIdentifier]}/`; }); }; /** * Generate the canonical version of a url based on the given base path and file path and in * the previously registered namespaces. * * @param {string} template The Twig Template * @param {string} _file The file path, may be relative and may contain namespaces. * * @return {string} The canonical version of the path */ Twig.path.parsePath = function (template, _file) { const {namespaces} = template.options; const file = _file || ''; const hasNamespaces = namespaces && typeof namespaces === 'object'; let path = (hasNamespaces ? Twig.path.expandNamespace(namespaces, file) : file); if (path === file) { path = Twig.path.relativePath(template, file); } return path; }; /** * Generate the relative canonical version of a url based on the given base path and file path. * * @param {Twig.Template} template The Twig.Template. * @param {string} _file The file path, relative to the base path. * * @return {string} The canonical version of the path. */ Twig.path.relativePath = function (template, _file) { let base; let basePath; let sepChr = '/'; const newPath = []; let file = _file || ''; let val; if (template.url) { if (typeof template.base === 'undefined') { base = template.url; } else { // Add slash to the end of path base = template.base.replace(/([^/])$/, '$1/'); } } else if (template.path) { // Get the system-specific path separator const path = require('path'); const sep = path.sep || sepChr; const relative = new RegExp('^\\.{1,2}' + sep.replace('\\', '\\\\')); file = file.replace(/\//g, sep); if (template.base !== undefined && file.match(relative) === null) { file = file.replace(template.base, ''); base = template.base + sep; } else { base = path.normalize(template.path); } base = base.replace(sep + sep, sep); sepChr = sep; } else if ((template.name || template.id) && template.method && template.method !== 'fs' && template.method !== 'ajax') { // Custom registered loader base = template.base || template.name || template.id; } else { throw new Twig.Error('Cannot extend an inline template.'); } basePath = base.split(sepChr); // Remove file from url basePath.pop(); basePath = basePath.concat(file.split(sepChr)); while (basePath.length > 0) { val = basePath.shift(); if (val === '.') { // Ignore } else if (val === '..' && newPath.length > 0 && newPath[newPath.length - 1] !== '..') { newPath.pop(); } else { newPath.push(val); } } return newPath.join(sepChr); }; return Twig; };