sitemesh的script提取


声明:本文转载自https://my.oschina.net/qixiaobo025/blog/1593655,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

背景

前文交代了一些使用sitemesh的背景土鳖的jsp改造

那么本着怎么简单怎么来的原则首先创建了一个通用模板

 

实现

  1. 修改pom文件引入sitemesh  

    <dependency>     <groupId>org.sitemesh</groupId>     <artifactId>sitemesh</artifactId>     <version>3.0.1</version> </dependency>

     

  2. 修改webxml增加对应filter 

    <filter>     <filter-name>sitemesh</filter-name>     <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class> </filter>   <filter-mapping>     <filter-name>sitemesh</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>

     

  3. 新建sitemesh3.xml

    <sitemesh>       <!-- 默认的装饰路径。如果没有配置其他的路径将启用默认路径,这个可以适用于所有路径 -->     <!-- Map default decorator. This shall be applied to all paths if no other paths match. -->     <mapping decorator="/WEB-INF/sitemesh/main.jsp"/>         <!-- 配置 不被装饰 的路径 -->     <!-- Exclude path from decoration. -->     <mapping path="/login/**" exclue="true"/>       <!-- 默认情况下,          sitemesh 只对 HTTP 响应头中 Content-Type 为 text/html 的类型进行拦截和装饰,          我们也可以添加更多的 mime 类型 -->     <mime-type>text/html</mime-type>     <mime-type>application/vnd.wap.xhtml+xml</mime-type>     <mime-type>application/xhtml+xml</mime-type>       <!--     Sitemesh 3 默认只提供了 body,title,head 种 tag 类型     我们可以添加自定义的tag规则 -->      </sitemesh>
  4. 我们除了登录之外的所有html页面进行装饰 

  5. 定义模板文件

    <%@ page contentType="text/html; charset=utf-8" %> <%@ page language="java" pageEncoding="UTF-8" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>     <title>         <sitemesh:write property='title'/>     </title>     <sitemesh:write property='head'/>   </head>     <body class="mainBody"> <sitemesh:write property='body'/> </body>   </html>
  6. 这样很轻易就定义了一套模板 

  7. 我们的目的是将script下沉到body的结尾 因此考虑增加scipt的提取
  8. 在sitemesh3.xml定义如下 

    <content-processor>     <tag-rule-bundle class="com.air.tqb.decorator.ScriptTagRuleBundle"/> </content-processor>

     

  9. 新建sciptTag 

    /**  * @author qixiaobo  */ public class ScriptTagRuleBundle implements TagRuleBundle {     private static final String TAG_SCRIPT = "script";       @Override     public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {         defaultState.addRule(TAG_SCRIPT, new ExportTagToContentRule(siteMeshContext, contentProperty.getChild(TAG_SCRIPT), false));     }       @Override     public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {       } }
  10. 修改main.jsp为

    <%@ page contentType="text/html; charset=utf-8" %> <%@ page language="java" pageEncoding="UTF-8" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>     <title>         <sitemesh:write property='title'/>     </title>     <sitemesh:write property='head'/>   </head>     <body class="mainBody"> <sitemesh:write property='body'/> <sitemesh:write property='script'/> </body>   </html>

     

  11. 不过考虑可能存在一些问题 scipt提取出来 那么其中的一些src要复写等等 还比较麻烦

  12. 重启服务后结果大失所望 script并没有被提取
  13. 检索发现也有国外小伙伴和我的思路一样 https://stackoverflow.com/questions/1914381/is-it-possible-to-extract-script-tags-using-sitemesh 【不过已经是8年前的啦 当时还是sitemesh2吧】
  14. 考虑一下为啥script并没有被识别成tag呢?
  15. 查看源码后发现 sitemesh将script标签识别成

    <YYINITIAL> {     "<!--" [^\[] ~"-->" { return TagTokenizer.Token.TEXT; } /* All comments unless they start with <!--[ */     "<!---->"           { return TagTokenizer.Token.TEXT; }     "<?" ~"?>"          { return TagTokenizer.Token.TEXT; }     "<!" [^\[\-] ~">"     { return TagTokenizer.Token.TEXT; }     "<![CDATA[" ~"]]>"  { return TagTokenizer.Token.TEXT; }     "<xmp" ~"</xmp" ~">" { return TagTokenizer.Token.TEXT; }     "<script" ~"</script" ~">" { return TagTokenizer.Token.TEXT; }     [^<]+               { return TagTokenizer.Token.TEXT; }     "<"                 { yybegin(ELEMENT); return TagTokenizer.Token.LT; }     "<!--["             { yybegin(ELEMENT); return TagTokenizer.Token.LT_OPEN_MAGIC_COMMENT; }     "<!["               { yybegin(ELEMENT); return TagTokenizer.Token.LT_CLOSE_MAGIC_COMMENT; } }
  16. 原来sitemesh不能支持script标签啊!

  17. 似乎走到了绝路
  18. 不过假设真的支持script 那么一些属性的设置也很麻烦啊 比如src 比如async等等
  19. 灵光一闪 既然script不支持 那么我们可以仿照jsp定义自己的标签啊! 
  20. 定义f6scriprt标签 该标签表示f6script中的数据将会移到body的末尾
  21. 那么思路豁然开朗 我们将之前reference中的一些js拆分 【jQuery等依然可以放在前面加载 大部分js依赖】非必须js 比如百度统计 比如客服js等等我们放在f6script块中
  22. 改造scriptTag

    package com.air.tqb.decorator;   import org.sitemesh.SiteMeshContext; import org.sitemesh.content.ContentProperty; import org.sitemesh.content.tagrules.TagRuleBundle; import org.sitemesh.content.tagrules.html.ExportTagToContentRule; import org.sitemesh.tagprocessor.State;   /**  * @author qixiaobo  */ public class ScriptTagRuleBundle implements TagRuleBundle {     private static final String TAG_SCRIPT = "f6script";       @Override     public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {         defaultState.addRule(TAG_SCRIPT, new ExportTagToContentRule(siteMeshContext, contentProperty.getChild(TAG_SCRIPT), false));     }       @Override     public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {       } }
  23. 修改模板文件为

    <%@ page contentType="text/html; charset=utf-8" %> <%@ page language="java" pageEncoding="UTF-8" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>     <title>         <sitemesh:write property='title'/>     </title>     <sitemesh:write property='head'/>   </head>     <body class="mainBody"> <sitemesh:write property='body'/> <sitemesh:write property='f6script'/> </body>   </html> 

     

  24. 在需要包装到结尾的js做如下处理 使用<f6script></f6script>进行包装

  25. js会乖乖的跑到了body结束符前
  26.  

本文发表于2017年12月22日 20:32
(c)注:本文转载自https://my.oschina.net/qixiaobo025/blog/1593655,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1881 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1