概观
大约2009年底,我写了一个简单的模板系统,在内部我们的设计师手册洁具型网站使用PHP/HTML.该系统的目标是通过PHP处理的自定义标记允许模板化其他纯HTML.例如,模板化页面可能如下所示:
<tt:Page template="templates/main.html">
<tt:Content name="leftColumn">
<p> blah blah </p>
...
</tt:Content>
<tt:Content name="rightColumn">
<p> blah blah </p>
...
</tt:Content>
</tt:Page>
Run Code Online (Sandbox Code Playgroud)
模板本身可能如下所示:
<html>
<head>...</head>
<body>
<div style="float:left; width:45%">
<tt:Container name="leftColumn" />
</div>
<div style="width:45%">
<tt:Container name="rightColumn" />
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
除了Page和Content/Container标签之外,核心中还包含一些其他标签,用于流控制,迭代集合,输出动态值等.框架的设计使得添加自己的一套很容易.标记在另一个前缀和命名空间下注册
自定义标签到PHP
我们如何解析这些自定义标签?由于无法保证HTML文件是格式良好的XML,因此XSLT/XPATH等解决方案将不可靠.相反,我们使用正则表达式来查找带有已注册前缀的标记,并用PHP代码替换它们.PHP代码是一个基于堆栈的设计...在遇到一个开始标记,表示创建该标记的物体压入堆栈,和它的"初始化函数"(如果有的话)延伸.每当遇到已注册的结束标记时,最新的对象将从堆栈中弹出,并且其"呈现函数"将运行.
因此,该框架替换PHP模板标签后,我们的示例页面看起来像这样(在房地产这有点丑陋):
<?php $tags->push('tt', 'Page', array('template'=>'templates/main.html')); ?>
<?php $tags->push('tt', 'Content', array('name'=>'leftColumn')); ?>
<p> blah blah </p>
...
<?php $tags->pop(); ?>
<?php $tags->push('tt', 'Content', array('name'=>'rightColumn')); ?>
<p> blah blah </p>
...
<?php $tags->pop(); ?>
<?php $tags->pop(); ?>
Run Code Online (Sandbox Code Playgroud)
好的,坏的,和 eval …
我正在创建一组ColdFusion自定义标记,旨在简化重用某些布局元素.我将以类似于以下的方式使用它们:
<cfimport prefix="layout" taglib="commonfunctions/layouttags">
<layout:fadingbox>
This text will fade in and out
</layout:fadingbox>
<layout:stockticker>
This text will scroll across the screen
</layout>
Run Code Online (Sandbox Code Playgroud)
为了使这些自定义标记生成的代码能够工作,需要将JavaScript文件链接到页面中,如下所示:
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)
我更喜欢在自定义标记内包含脚本,而不是让用户自己包含它.问题是JavaScript文件每页只应包含一次.在第一次使用其中一个自定义标签后,我希望在同一页面上对相同标签的后续调用,以避免重复<script>标签.我想到我可以这样做:
<cfif NOT isDefined("Caller.LayoutTagInitialized")>
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
</cfif>
<cfset Caller.LayoutTagInitialized = 1>
Run Code Online (Sandbox Code Playgroud)
......但它似乎不优雅.
我想知道,还有更好的方法吗?
你会如何实现这个?
编辑 - 澄清:
如果我上面写的内容没有意义,这里有一个更详细的例子:
如果我有这样的自定义标签:
<cfif ThisTag.ExecutionMode EQ "start">
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
<div class="mytag">
<cfelse>
</div>
</cfif>
Run Code Online (Sandbox Code Playgroud)
...我有CFML标记调用标签,如下所示:
<layout:mytag>
One
</layout:mytag>
<layout:mytag>
Two
</layout:mytag>
<layout:mytag>
Three
</layout:mytag>
Run Code Online (Sandbox Code Playgroud)
...我希望生成如下的HTML:
<!-- Script included only the first time the tag …Run Code Online (Sandbox Code Playgroud) 我无法获得宽度和高度属性以适用于我的自定义标签,请参阅下面的代码:CSS
x-slider
{
width: 1000px;
height: 300px;
border: 1px black solid;
background-color: #0000ff;
}
Run Code Online (Sandbox Code Playgroud)
HTML
<body><x-slider id="CoolPics" page="home"></x-slider></body>
Run Code Online (Sandbox Code Playgroud)
使用Javascript
var x = document.registerElement('x-slider', {
prototype: Object.create(HTMLDivElement.prototype), extends: 'div'
});
Run Code Online (Sandbox Code Playgroud)
我添加了DIV对象的扩展,看看是否允许我指定高度,因为某些标签不允许高度.只有某些css属性可以使用自定义标签吗?边框和背景颜色都显示出来,我也尝试过切换到最小和最大高度.请限制对问题的回答,而不是主观论点是否应该使用自定义标签,这使得每次发布有关自定义标签超过这些响应的帖子时,更难以搜索答案.
我正在使用Java中的自定义标记,我收到一个错误.让我详细说明所涉及的文件:
我的tag.tld(路径为:\ WEB-INF\tlds\tag.tld)具有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>0.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>message</shortname>
<tag>
<description>StringReverseTag</description>
<name>string</name>
<tag-class>mytag.StringReverseTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>data</name>
<required>true</required>
</attribute>
</tag>
</taglib>
Run Code Online (Sandbox Code Playgroud)
ReverseEx.jsp
<%@page contentType="text/html" pageEncoding="UTF-8" language="java"%>
<!DOCTYPE html>
<%@taglib uri="/WEB-INF/tlds/tag.tld" prefix="jen" %>
<jen:string data="EARTH"/>
<html>
<head>
<title>Tag Example</title>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
助手班:
package chap4;
import java.io.IOException;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
public class StringReverseTag extends SimpleTagSupport{
private String data;
public void setData(String data) {
this.data=data;
}
@Override
public void …Run Code Online (Sandbox Code Playgroud) 我有以下HTML代码:
<mytag>
Just Some Text
</mytag>
Run Code Online (Sandbox Code Playgroud)
我有这个jQuery命令
$('mytag').each(function () { alert($(this).html()); });
Run Code Online (Sandbox Code Playgroud)
在除IE之外的所有浏览器中我都获得了内部HTML,在IE中我不是.任何人都可以阐明这个谜团吗?我用IE8,Mozilla,Opera,Chrome和Safari测试了这个
我有一个自定义标记,当用户标识传递给用户时,它会向用户的浏览器显示简历信息.我想将带有html输出的变量返回到调用页面,以便cfc可以使用它.任何人都可以评论如何在变量中返回html?是在正确的方式下?调用页面看起来像
In custom tag <cfset caller[attributes.returnVar] = '#cv_content#'>
calling page <cf_cv_info user_id="295725" returnVar="foo">
Run Code Online (Sandbox Code Playgroud)
谢谢
我想将数组传递给自定义标签。这可能吗?我有一个arry arrayProd。在我的cfm中,我正在调用自定义标签:
<cf_cu_show_productcategories thename="#thename#" thenameprod="#thenameprod#" arrayProd="#arrayProd#">
Run Code Online (Sandbox Code Playgroud)
自定义标签:
<cfparam name="attributes.thename" default="">
<cfparam name="attributes.thenameprod" default="">
<cfparam name="attributes.arrayProd" type="array" default="">
Run Code Online (Sandbox Code Playgroud)
在自定义标签中使用此arrayProd会导致“变量ARRAYPROD未定义”。
我对ColdFusion有点新鲜(来自Java/OOP世界)
我有一个自定义标记,它在cfscript中运行一些东西并输出一个值.我想让这个自定义标签(让我们称之为A)调用另一个自定义标签(让我们称之为B,一种具有某种"静态"功能的更通用的自定义标签),并带有一定的参数.
如何从A中拨打B?如何使用A中B的返回值?
A的代码
<cfscript>
//Call to other custom tag here?:
//foo = [CUSTOMTAG param="stuff"];
value = foo;
</cfscript>
<cfoutput>#value#</cfoutput>
Run Code Online (Sandbox Code Playgroud)