2014-10-28 36 views
0

在小鬍子/處理程序或js中的任何模板系統中,是否有任何工具可以收集模板引用的所有變量?小鬍子/把手模板:從模板中找出上下文數據結構html

例如,給定的輸入

templateHTML:

<div class="{{divclass}}"> 
    {#item}} 
    <h1>{{title}}</h1> 
    <span>{{text}}</span> 
    {{/item}} 
</div> 

MyTemplateTool.getTemplateData(templateHTML)

我試着用搜索引擎周圍,並檢查了車把文檔,但可能使用時返回

{ 
    divclass: "", 
    item: { 
    title: "", 
    text: "" 
    } 
} 

找不到合適的東西

回答

0

我相信這只是.。查看相關的docs on paths。例如:

{{#srcs}} 
    <script src="{{.}}"></script> 
{{/srcs}} 
+0

我不確定我們在這裏談論的是同樣的事情嗎?我需要知道在模板中使用了哪些變量,當我在模板中使用字符串或dom時 – tonsteri 2014-10-28 07:35:43

+0

爲什麼需要從模板中獲取模板上下文?你的代碼不應該已經生成該上下文並將其傳入? – hlfcoding 2014-10-28 07:38:22

+0

這是一種情況,我需要爲用戶製作的html模板生成一個'內容編輯器'。我不確定這是否應該走,但我很好奇,如果有人知道這個工具 – tonsteri 2014-10-28 07:43:28

0

我腦子裏想的一樣,我認爲這是值得一邊寫東西,所以在這裏你去:

import java.io.IOException; 
import java.nio.charset.Charset; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.util.LinkedHashMap; 
import java.util.Map; 
import java.util.TreeMap; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class MustacheSchemaBuilder 
{ 
    static String javaIdentifierRegExp = "[a-zA-Z_$0-9]+"; 
    static String tab = " "; 
    static Format format = Format.java; 

    enum Format { 
     json, 
     java, 
     ; 
    } 

    enum TagType { 
     variable("\\{\\{\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"), 
     escapedVariable("\\{\\{\\{\\s*" + javaIdentifierRegExp + "\\s*\\}\\}\\}"), 
     sectionStart("\\{\\{#\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"), 
     invertedSectionStart("\\{\\{\\^\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"), 
     sectionEnd("\\{\\{/\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"), 
     //partial("\\{\\{>\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"), 
     // no support for set delimiters or partials 
     ; 

     Pattern pat; 
     private TagType(String aRegExp) { 
      pat = Pattern.compile(aRegExp); 
     } 

     public Pattern getPattern() { return pat; }; 
    } 

    class Tag{ 
     public TagType type; 
     public String identifier; 
     Tag(TagType aType, String aIdentifier) { type = aType; identifier = aIdentifier;} 

     public String toString() { return type.name() + " : " + identifier; } 

     @Override 
     public boolean equals(Object aOther) { 
      if(!(aOther instanceof Tag)) return false; 
      Tag ot = (Tag) aOther; 
      return ot.type.equals(this.type) && ot.identifier.equals(this.identifier); 
     } 

     @Override 
     public int hashCode() {return identifier.hashCode();} 
    } 

    class Node { 
     public Section parent; 
     public Tag tag; 
     Node(Section aParent, Tag aTag){parent = aParent; tag = aTag; if(parent != null) parent.children.put(tag, this);} 

     @Override 
     public int hashCode() {return tag.hashCode();} 

     public int depth() { 
      int depth = 0; 
      Node currentNode = this; 
      while(currentNode.parent != null) { 
       depth++; 
       currentNode = currentNode.parent; 
      } 
      return depth; 
     } 

     @Override 
     public String toString() { 
      StringBuilder sb = new StringBuilder(); 
      for(int i = 0; i < this.depth(); i++) sb.append(tab); 
      switch(format) { 
      case java: 
       sb.append("public Object ").append(tag.identifier).append(";\n"); 
       break; 
      case json: 
      default: 
       sb.append(tag.identifier).append(": {},\n"); 
      } 
      return sb.toString(); 
     } 
    } 

    class Section extends Node{ 
     public Map<Tag, Node> children = new LinkedHashMap(); 
     Section(Section aParent, Tag aTag) { super(aParent, aTag); }; 

     @Override 
     public String toString() { 
      StringBuilder sb = new StringBuilder(); 
      for(int i = 0; i < this.depth(); i++) sb.append(tab); 
      switch(format) { 
      case java: 
       sb.append("public Object ").append(tag.identifier).append(" = new Object() {\n"); 
       for(Node child : this.children.values()) sb.append(child); 
       for(int i = 0; i < this.depth(); i++) sb.append(tab); 
       sb.append("};\n"); 
       break; 
      case json: 
      default: 
       sb.append(tag.identifier).append(": {\n"); 
       for(Node child : this.children.values()) sb.append(child); 
       for(int i = 0; i < this.depth(); i++) sb.append(tab); 
       sb.append("},\n"); 
      } 
      return sb.toString(); 
     } 
    } 

    class MustacheSchemaBuildException extends Exception { 
     private static final long serialVersionUID = 1L; 
     MustacheSchemaBuildException(String aMessage) {super(aMessage);} 
    } 

    Section rootSection; 

    public MustacheSchemaBuilder(String aContents) throws Exception 
    { 
     TreeMap<Integer, Tag> tagMap = new TreeMap(); 
     for(TagType type : TagType.values()) { 
      populateMap(tagMap, type, aContents); 
     } 
     System.out.println(tagMap); 

     rootSection = new Section(null, new Tag(TagType.sectionStart, "$root$")); 
     Section currentSection = rootSection; 

     for(Tag tag : tagMap.values()) { 
      if(currentSection.tag.type == TagType.invertedSectionStart) { 
       if(tag.type == TagType.sectionEnd) { 
        if(!tag.identifier.equals(currentSection.tag.identifier)) 
         throw new MustacheSchemaBuildException("The end tag: " + tag.identifier + " doesn't match the expected start tag: " + currentSection.tag.identifier + "\n\n" + rootSection); 
        currentSection = currentSection.parent; 
       } 
       continue; 
      } 
      switch(tag.type) 
      { 
      case variable: 
       if(!currentSection.children.containsKey(tag)) 
        new Node(currentSection, tag); 
       break; 
      case sectionStart: 
       Tag invertedSectionStartTag = new Tag(TagType.invertedSectionStart, tag.identifier); 
       if(!(currentSection.children.containsKey(tag) || currentSection.children.containsKey(invertedSectionStartTag))) 
        new Section(currentSection, tag); 
       currentSection = (Section)currentSection.children.get(tag); 
       break; 
      case invertedSectionStart: 
       Tag sectionStartTag = new Tag(TagType.sectionStart, tag.identifier); 
       if(!(currentSection.children.containsKey(tag) || currentSection.children.containsKey(sectionStartTag))) 
        new Section(currentSection, tag); 
       currentSection = (Section)currentSection.children.get(sectionStartTag); 
       break; 
      case sectionEnd: 
       if(!tag.identifier.equals(currentSection.tag.identifier)) 
        throw new MustacheSchemaBuildException("The end tag: " + tag.identifier + " doesn't match the expected start tag: " + currentSection.tag.identifier + "\n\n" + rootSection); 
       currentSection = currentSection.parent; 
       break; 
      default: 
      } 
     } 
    } 

    public void build() { 
     System.out.println(rootSection); 
    } 

    public static void main(String[] args) throws Exception 
    { 
     String contents; 
     try { 
      contents = readFile(args[0], Charset.defaultCharset()); 

     }catch(Exception e) 
     { 
      System.out.println("Unable to open file!"); 
      throw e; 
     } 

     MustacheSchemaBuilder builder = new MustacheSchemaBuilder(contents); 

     builder.build(); 
    } 

    void populateMap(Map<Integer, Tag> map, TagType aType, String aContents) { 
     Matcher m = aType.getPattern().matcher(aContents); 
     while(m.find()) { 
      int start = m.start() + 3; 
      if(aType == TagType.variable) start = m.start() + 2; 
      map.put(m.start(), new Tag(aType, aContents.substring(start, m.end() - 2).trim())); 
     } 
    } 

    static String readFile(String path, Charset encoding) throws IOException 
    { 
     byte[] encoded = Files.readAllBytes(Paths.get(path)); 
     return new String(encoded, encoding); 
    } 
} 

給在命令行模板文件路徑 - 你需要的Java 7或更高來打開文件,或者您可以重寫readFile - 方法。您可以通過更改類頂部的格式來生成json或java'模式'。 '模式'被寫入標準輸出,你可以從那裏複製並粘貼到你需要的地方。希望這可以幫助。啊!這不支持部分或設置分隔符,但如果你開始寫支持ping給我,因爲我可能需要它:)