在js中的mustache / handlerbars或任何模板系统中, 是否有任何工具来收集模板引用的所有变量?
例如,给定输入
templateHTML:
<div class="{{divclass}}">
{#item}}
<h1>{{title}}</h1>
<span>{{text}}</span>
{{/item}}
</div>
将返回
{
divclass: "",
item: {
title: "",
text: ""
}
}
使用时像MyTemplateTool.getTemplateData(templateHTML)
我尝试使用谷歌搜索并查看了车把文档,但找不到合适的内容
答案 0 :(得分:0)
我相信它只是.
。请参阅相关的docs on paths。例如:
{{#srcs}}
<script src="{{.}}"></script>
{{/srcs}}
答案 1 :(得分: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“模式”。 'schema'被写入stdout,你可以从那里复制它并将其粘贴到你需要的地方。希望这可以帮助。啊!这不支持partials或set delimiters,但是如果你开始写支持ping我就像我想要的那样:)