src/template.mjs gelöscht
This commit is contained in:
		
							
								
								
									
										139
									
								
								src/template.mjs
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								src/template.mjs
									
									
									
									
									
								
							@@ -1,139 +0,0 @@
 | 
				
			|||||||
import fs from "fs";
 | 
					 | 
				
			||||||
import path from "path";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default class {
 | 
					 | 
				
			||||||
  #views;
 | 
					 | 
				
			||||||
  #globals;
 | 
					 | 
				
			||||||
  #cache;
 | 
					 | 
				
			||||||
  #templates;
 | 
					 | 
				
			||||||
  #debug;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor() {
 | 
					 | 
				
			||||||
    this.#views = "./views";
 | 
					 | 
				
			||||||
    this.#globals = {};
 | 
					 | 
				
			||||||
    this.#debug = false;
 | 
					 | 
				
			||||||
    this.#cache = true;
 | 
					 | 
				
			||||||
    this.#templates = new Map();
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  set debug(d) {
 | 
					 | 
				
			||||||
    this.#debug = !!d;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  set views(v) {
 | 
					 | 
				
			||||||
    this.#views = v;
 | 
					 | 
				
			||||||
    this.readdir(v);
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  set globals(g) {
 | 
					 | 
				
			||||||
    this.#globals = g;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  set cache(c) {
 | 
					 | 
				
			||||||
    this.#cache = !!c;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  readdir(dir, root = dir) {
 | 
					 | 
				
			||||||
    for(const d of fs.readdirSync(`${path.resolve()}/${dir}`)) {
 | 
					 | 
				
			||||||
      if(d.endsWith(".html")) { // template
 | 
					 | 
				
			||||||
        const file = path.parse(`${dir.replace(this.#views, '')}/${d}`);
 | 
					 | 
				
			||||||
        const t_dir = file.dir.substring(1);
 | 
					 | 
				
			||||||
        const t_file = file.name;
 | 
					 | 
				
			||||||
        this.getTemplate(!t_dir ? t_file : `${t_dir}/${t_file}`);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      else { // directory
 | 
					 | 
				
			||||||
        this.readdir(`${dir}/${d}`, root);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getTemplate(tpl) {
 | 
					 | 
				
			||||||
    let template = {};
 | 
					 | 
				
			||||||
    let cache = false;
 | 
					 | 
				
			||||||
    if(this.#cache && this.#templates.has(tpl)) {
 | 
					 | 
				
			||||||
      template = this.#templates.get(tpl);
 | 
					 | 
				
			||||||
      cache = template.cached;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      template = {
 | 
					 | 
				
			||||||
        code: fs.readFileSync(`${this.#views}/${tpl}.html`, "utf-8"),
 | 
					 | 
				
			||||||
        cached: new Date()
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      this.#templates.set(tpl, template);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return [
 | 
					 | 
				
			||||||
      template.code,
 | 
					 | 
				
			||||||
      (this.#debug ? `<!-- ${tpl}.html ` + (cache ? `cached ${template.cached}` : `not cached`) + " -->" : "")
 | 
					 | 
				
			||||||
    ].join("");
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  render(file, data = {}, locals) {
 | 
					 | 
				
			||||||
    data = { ...data, ...locals, ...this.#globals };
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      const code = 'with(_data){const __html = [];' +
 | 
					 | 
				
			||||||
        '__html.push(\`' +
 | 
					 | 
				
			||||||
        this.getTemplate(file)
 | 
					 | 
				
			||||||
          .replace(/[\t]/g, ' ')
 | 
					 | 
				
			||||||
          .split('\`').join('\\\`')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/{{--(.*?)--}}/g, "") // comments
 | 
					 | 
				
			||||||
          .replace(/{{(.+?)}}/g, '\`,$1,\`') // yield variable
 | 
					 | 
				
			||||||
          .replace(/{!!(.+?)!!}/g, '\`,this.escape($1),\`') // yield escaped variable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@js/g, "`);") // inject bare javascript
 | 
					 | 
				
			||||||
          .replace(/@endjs/g, ";__html.push(`")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@mtime\((.*?)\)/g, `\`);__html.push(this.getMtime('$1'));__html.push(\``)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@include\((.*?)\)/g, (_, inc) => this.render(inc, data)) // include template
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@for\((.*?)\)$/gm, `\`);for($1){__html.push(\``)
 | 
					 | 
				
			||||||
          .replace(/@endfor/g, `\`);}__html.push(\``)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@each\((.*?) as (.*?)\)/g, `\`);this.forEach($1,($2,key)=>{__html.push(\``) // foreach for the poor
 | 
					 | 
				
			||||||
          .replace(/@endeach/g, "\`);});__html.push(`")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          .replace(/@elseif\((.*?)\)(\)?)/g, `\`);}else if($1$2){__html.push(\``) // if lol
 | 
					 | 
				
			||||||
          .replace(/@if\((.*?)\)(\)?)/g, `\`);if($1$2){__html.push(\``)
 | 
					 | 
				
			||||||
          .replace(/@else/g, "`);}else{__html.push(`")
 | 
					 | 
				
			||||||
          .replace(/@endif/g, "`);}__html.push(`") +
 | 
					 | 
				
			||||||
        '\`);return __html.join(\'\').replace(/\\n\\s*\\n/g, "\\n");}';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return (new Function("_data", code)).bind({
 | 
					 | 
				
			||||||
        escape: this.escape,
 | 
					 | 
				
			||||||
        forEach: this.forEach,
 | 
					 | 
				
			||||||
        getMtime: this.getMtime
 | 
					 | 
				
			||||||
      })(data);
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
      console.log(file, err.message);
 | 
					 | 
				
			||||||
      return (this.#debug ? `${err.message} in ${file}` : '');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  escape(str) {
 | 
					 | 
				
			||||||
    return (str + '')
 | 
					 | 
				
			||||||
      .replace(/&/g, '&')
 | 
					 | 
				
			||||||
      .replace(/</g, '<')
 | 
					 | 
				
			||||||
      .replace(/>/g, '>')
 | 
					 | 
				
			||||||
      .replace(/"/g, '"')
 | 
					 | 
				
			||||||
      .replace(/'/g, ''')
 | 
					 | 
				
			||||||
      .replace(/{/g, '{')
 | 
					 | 
				
			||||||
      .replace(/}/g, '}')
 | 
					 | 
				
			||||||
    ;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  forEach(o, f) {
 | 
					 | 
				
			||||||
    if(Array.isArray(o))
 | 
					 | 
				
			||||||
      o.forEach(f);
 | 
					 | 
				
			||||||
    else if(typeof o === "object")
 | 
					 | 
				
			||||||
      Object.keys(o).forEach(k => f.call(null, o[k], k));
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      throw new Error(`${o} is not a iterable object`);
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getMtime(file) {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      return +(fs.statSync(path.normalize(process.cwd() + file)).mtimeMs + '').split(".")[0];
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
      console.log(err);
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user