Giter Site home page Giter Site logo

jello's Introduction

jello ['dʒeləu]

针对服务端为 JAVA + Velocity 的前端集成解决方案。

为优化前端开发而生,提供前后端开发分离、自动性能优化、模块化开发机制等功能。

本项目基于 fis2, 基于 fis3 的版本请移步至:https://github.com/fex-team/fis3-jello

目录

前后端分离

基于 velocity 模板引擎实现前后端分离,让前端攻城师更专注于 JS、CSS、VM(velocity 模板文件) 文件编写。 我们提供一种简单的机制,模拟线上环境,让你轻松的预览线上效果。

比如:创建一个 vm velocity 模板文件后,基于我们的工具,你可以直接预览此模板文件的内容, 在相应的目录创建一个同名 json 文件,按与后端开发人员约定好的数据格式, 在此 json 文件中添加测试数据便能自动与模板变量绑定上。

使用此机制可以让前端开发流程与后端开发完全分离,后端开发人员只需关心渲染哪个模板文件和添加相应的模板数据。

自动性能优化

我们基于 velocity 开发了些扩展标签 (directive),如:html、head、body、script、style、widget... 如果你采用我们提供的标签 (directive) 组织代码,无论按什么顺序组织,我们可以保证所有 css 内容集中在头部输出,所有的 js 集中在底部输出,以达到一个性能优化的效果。

另外结合自动打包配置,可以让多个 js/css 资源合并成一个文件,更大程度的优化性能。

模板继承机制

扩展 velocity 实现类 smarty 的模板继承功能,让模板能够得到更充分的复用。

将多个页面间相同的部分提取到一个 layout.vm 文件里面,每个页面只需填充自己独有的内容。

更多细节查看模板继承

模块化开发

提供 html、css、js 模块化机制,包括 widget 组件化与 js amd 加载机制,让内容更好的拆分与复用。

简化环境安装

内嵌 j2ee 开发服务器,你无需再折腾 j2ee 环境搭建。直接通过 jello server start 就能开起服务,预览页面。

如何使用

安装

  • 安装 nodejs&npm

  • 安装 java

  • 安装jello & lights

     npm install lights -g
     npm install jello -g
     jello -v

快速上手

  • 通过 lights 下载 jello-demo,或者通过 git clone jello-demo.

     lights install jello-demo
  • 安装插件

    npm install -g fis-parser-marked
    npm install -g fis-parser-utc
    npm install -g fis-parser-sass
  • 编译预览

     cd jello-demo
     jello release
     jello server start
  • 预览: localhost:8080

  • 在线 demo.

jello 命令

三条命令满足所有开发需求

     jello --help

     Usage: jello <command>

     Commands:

        release     build and deploy your project
        install     install components and demos
        server      launch a embeded tomcat server

     Options:

        -h, --help     output usage information
        -v, --version  output the version number
        --no-color     disable colored output

模板继承

提供类似 smarty 的模板集成机制, 被继承的模板中的所有 block 标签都可以被覆盖。

  1. layout.vm
<!DOCTYPE html>
  #html("example:static/js/mod.js")

  #head()
    <meta charset="utf-8"/>
    <meta content="" name="description">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Demo</title>
    #require("example:static/css/bootstrap.css")
    #require("example:static/css/bootstrap-theme.css")
    #require("example:static/js/jquery-1.10.2.js")
    #require("example:static/js/bootstrap.js")
  #end ## end head

#body()
<div id="wrapper">
  #block("body_content")
      This is body.
  #end
</div>
#end ## end body

#require("example:page/layout.vm")
#end ## end html
  1. index.vm
#extends("layout.vm")

#block("body_content")
<h1>Hello Demo</h1>

    #widget("example:widget/header/header.vm")

    #script()
    // var widgetA = require("example:widget/widgetA/widgetA.js");

    require.async("example:widget/widgetB/widgetB.js", function(api) {
    api.sayHelloWorld();
    });
    #end ## end script
#end ## end block

#require("example:page/index.vm")
#end

模板数据绑定

每个 page 目录下的模板页面都会自动绑定上 test 目录下同名的 json 数据,同时还支持添加同名 jsp 脚本动态添加。

  1. test/page/index.json
{
    "title": "This will be override in index.jsp.",
    "subtitle": "This is subtitle."
}
  1. test/page/index.jsp **注意:**这里任何内容输出都会被屏蔽。
<%@ page import="org.apache.velocity.context.Context" %><%

    Context context = (Context)request.getAttribute("context");


    context.put("title", "Welcome to jello.");
%>
  1. page/index.vm
<h1>$title</h1>
<h2>$subtitle</h2>
  1. 输出结果
<h1>Welcome to jello.</h1>
<h2>This is subtitle.</h2>

页面模拟

通过创建 vm 文件可以创建页面,但是访问路径是固定的 ${namespace}/page/${页面路径},此路径与线上地址不一致怎么办?

可以通过添加 server.conf 文件,如下面的栗子,当请求 /testpage 的时候,实际上渲染的是 example/page/testpage 页面

rewrite ^\/testpage /example/page/testpage

处理 page 下的 vm 文件,还可重定向 test 的各种 json 文件和 jsp 文件。如

rewrite ^\/ajaxHander /test/page/ajaxHandler.jsp

rewrite ^\/somejsonfile /test/page/data.json

server.conf 支持 rewrite, redirect 两种指令。

插件说明

基于 velocity 扩展了以下标签 (directive)。

html

代替<html>标签,设置页面运行的前端框架,以及控制整体页面输出。

语法: #html([$framework[, $attrs]])body #end

#html("fis-site:static/js/mod.js", "lang", "zh")
...
body content.
...
#end

输出

<html lang="zh">
...
body content
...
</html>

head

代替<head>标签,控制CSS资源加载输出。

语法: #head([$attrs]) body #end

#head()
<meta charset="utf-8"/>
#end

body

代替<body>标签,控制JS资源加载输出。

语法: #body([$attrs]) body #end

#html("home:static/lib/mod.js")
  #head()
  <meta charset="utf-8"/>
  #end

  #body()
      ...
  #end
#end

script

代替<script>标签,收集使用JS组件的代码块,控制输出至页面底部。

语法: #script([$attrs]) body #end

#html("home:static/lib/mod.js")
  #head()
  <meta charset="utf-8"/>

    ## 通过script插件收集加载组件化JS代码
    #script()
    require.async("home:static/ui/B/B.js");

    console.log('here');
    #end
  #end

  #body()
      ...
  #end
#end

style

代替<style>标签,收集使用CSS组件的代码块,控制输出至页面头部。

语法: #style([$attrs]) body #end

#html("home:static/lib/mod.js")
  #head
  <meta charset="utf-8"/>

    #style()
    @import url(xxx.css);

    body {
        color: #fff;
    }
    #end
  #end

  #body
      ...
  #end
#end

require

通过静态资源管理框架加载静态资源。

语法: #require( $uri )

#html("home:static/lib/mod.js")
  #head()
  <meta charset="utf-8"/>

    ## 通过script插件收集加载组件化JS代码
    #script()
    require.async("home:static/ui/B/B.js");

    console.log('here');
    #end
  #end

  #body()
    #require("home:static/index/index.css")
  #end
#end

widget

调用模板组件,渲染输出模板片段。

语法: #widget( $uri )

 #html("home:static/lib/mod.js")
   #head()
   <meta charset="utf-8"/>

     ## 通过script插件收集加载组件化JS代码
     #script()
     require.async("home:static/ui/B/B.js");

     console.log('here');
     #end
   #end

   #body()
     #require("home:static/index/index.css")
     #widget("home:widget/A/A.tpl")
   #end
 #end

uri

定位线上资源,允许跨模块(project)。

语法: #uri( $uri )

 #html("home:static/lib/mod.js")
   #head()
   <meta charset="utf-8"/>
   #end

   #body()
       #uri("home:static/css/bootstrap.css")
   #end
 #end

配置

参考fis配置

后端整合

后端一般都是使用 spring 来开发,所以这里给出 spring 集成方式,其他运行模式请参考。关于 spring 整合的 demo 可以看这里

对于后端来说,只需关心前端输出的模板文件、静态资源和 map json文件。

默认的输出路径是:

  • 模板文件: /templates/**.vm
  • 静态资源: /static/**
  • map json 文件:/WEB-INF/config/xxx-map.json

为了让 velocity 能正常渲染模板,需要设置模板目录,以及将 fis 提供的自定义 diretives 启动。 配置内容如下:

<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
    <property name="resourceLoaderPath" value="/velocity 模板目录/"/>
    <property name= "velocityProperties">
        <props>
            <prop key="input.encoding">utf-8</prop>
            <prop key="output.encoding">utf-8</prop>
            <!--启用 fis 提供的自定义 diretives 启动-->
            <prop key="userdirective">com.baidu.fis.velocity.directive.Html, com.baidu.fis.velocity.directive.Head, com.baidu.fis.velocity.directive.Body, com.baidu.fis.velocity.directive.Require, com.baidu.fis.velocity.directive.Script, com.baidu.fis.velocity.directive.Style, com.baidu.fis.velocity.directive.Uri, com.baidu.fis.velocity.directive.Widget, com.baidu.fis.velocity.directive.Block, com.baidu.fis.velocity.directive.Extends</prop>
        </props>
    </property>
</bean>

为了让 fis 自定义的 directive 能够正常读取 map.json 文件,需要添加一个 bean 初始化一下。

<!--初始 fis 配置-->
<bean id="fisInit" class="com.baidu.fis.velocity.spring.FisBean" />

默认 map json 文件是从 /WEB-INF/config 文件夹下读取的,如果有修改存放地址,则需要添加一个 fis.properties 文件到 /WEB-INF/ 目录。 内容如下:

# 相对与 WEB-APP 根目录。
mapDir = /velocity/config

fis 框架代码可以在此下载。所有代码开源在 github 上。

fis.properties

fis 中有以下默认配置项,如果需要修改,请在项目根目录下面新建 fis.properties 文件。此文件将被 release 到 /WEB-INF/fis.properties

# 本地调试才需要修改,与后端结合不需要设置。
# 设置 velelocity 模板存放目录,目录相对于 webapp 根目录。
views.path = /WEB-INF/views

# map json 所在目录。
mapDir = /WEB-INF/config

encoding = UTF-8

# 是否自动输出 resouceMap,此选项跟 mod.js 有关,没有 resouceMap 异步js 无法加载。
sourceMap = true

默认

更多资料

jello's People

Contributors

2betop avatar lily-zhangying avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jello's Issues

jello-demo中livereload无效

我直接clone了一个jello-demo做测试,结果发现执行jello release -wL后,虽然cmd提示了livereload的端口号为8132,和fis一样,但是浏览的页面结果并没有注入livereload的js引用。

还有就是,感觉编译有点慢,修改一个.vm文件,需要4秒+的时间。

tomac 404

jello server start后404找不到页面

release过了

可是不行

是否可以支持 widget 目录下的数据绑定

jello 现在数据绑定是依据 page 进行绑定的,是否考虑也可以按 widget 去绑定数据?通常情况下,widget也是共用的,这样也可以从另个角度解决数据共用的问题

-- page
    -- page1

-- widget
    -- widget1

-- test
    -- page.json

    -- page
        -- page1
            -- page1.json

    -- widget
        -- widget1
            -- widget1.json

您好 我写了如下一段代码

fis.config.set('roadmap.path', [
    {
        reg: /^\/components\/(?!lib\/).*\.js$/i,
        isMod: true,
        release: '${statics}/$&'
    }, {
        reg: /^\/.*\/page\/(.*)$/i,
        useCache: false,
        release:"${templates}/$&"
    }, {
        reg: /^\/common\/widget\/ui\/library\/(.*)/i,
        release: false
    },
    {
        //一级同名组件,可以引用短路径,比如modules/jquery/juqery.js
        //直接引用为var $ = require('jquery');
        reg: /^\/.*\/(widget)\/(?!lib\/)(.*)\.(js)$/i,
        //是组件化的,会被jswrapper包装
        isMod: true,
        release: '${statics}/$&'
    },{
        reg: /^\/.*\/(static)\/(.*)\.(js)$/i,
        //是组件化的,会被jswrapper包装
        isMod: true,
        release: '${statics}/$&'
    },
    {
        //less的mixin文件无需发布
        reg: /^(.*)mixin\.less$/i,
        release: false
    }
    //, {
    //    //其他css文件 ///^\/(?!fa|plugin)(.*)\.(css|less)$/i, 非某个文件夹的正则
    //    reg: /^(.*)\.(css|less)$/i,
    //    release: '${statics}/$&'
    //}
    , {
        //前端模板
        reg: '**.tmpl',
        //当做类js文件处理,可以识别__inline, __uri等资源定位标识
        isJsLike: true,
        //只是内嵌,不用发布
        release: false
    }, {
        reg: /.*\.(html|jsp|tpl|vm|htm|asp|aspx|php)$/,
        useCache: false
    }, {
        reg: "README.md",
        release: false
    }
    //, {
    //    reg: "**",
    //    release: '${statics}/$&'
    //}
].concat(fis.config.get('roadmap.path', [])));

其中配置了这一段

{
        reg: /^\/common\/widget\/ui\/library\/(.*)$/i,
        release: false
}

虽然配置了 但是为什么我现在文件目录下的/common/widget/ui/library/xxx的文件还是被release了呢

jello需要后端配合什么?

我想了解一下后端的实现原理,如果项目用jello,需要后端做哪些工作,生产环境的json怎么和模板绑定?

【已解决】#parent() 指令失效

a.vm 文件:

#blocks('div')
<div>div a</div>
#end

b.vm 文件:

#extends('a.vm')
#blocks('div')
#parent();
<div>div b</div>
#end
#end

页面输出:

#parent()
div b

而不是

div a
div b

就是 #paraent() 指令失效,并没有继承下来。

jello release -o 处理不正确

velocity 里面 ## 为注释,-o 的时候需要把注释删除,否则多行合并后,本来不是注释的部分变成了注释。

Jello在linux上打包特别慢,求加快

执行jello打包竟然需要432秒,即6分钟左右,求大神帮忙优化。

打包脚本如下:build-online-complete.sh

#!/bin/sh
cd fe
jello release -r common -copmd output
jello release -r home -copmd output

#maven打包
#...

执行结果如下:

woody@ubuntu:~/workspace/ups-plat$ sh build-online-complete.sh 
[INFO] ------------------------------------------------------------------------
[INFO] FIS build
[INFO] ------------------------------------------------------------------------

 δ 0ms

 Ω .............................. 15556ms

 δ 12ms

 Ω     ...................................................................................................................................................................     432393ms
build package ...

Jello版本

woody@ubuntu:~/workspace/ups-plat$ jello -v

  v1.0.2

打包之后resourceMap不全的问题,求教。

不打包的情况下,一切正常。打包之后出现问题。
我的config:

var workPath = '/home/work/tools/tomcat/webapps/';

fis.config.set('roadmap.path', [{
    reg: /^\/page\/(.*\.(js|less|css|jpg|jpeg|png|gif))$/i,
    isMod: true,
    release: '${statics}/${namespace}/page/$1',
    url: '${webname}/${namespace}/page/$1'
},
{
    reg: /^\/widget\/(.*\.(js|less|css|jpg|jpeg|png|gif))$/i,
    isMod: true,
    release: '${statics}/${namespace}/widget/$1',
    url: '${webname}/${namespace}/widget/$1'
},
{
    reg: /^\/(static)\/(.*)/i,
    release: '${statics}/${namespace}/$2',
    url: '${webname}/${namespace}/$2'
},
{
    reg: /^\/data\/(.*\.json)$/i,
    release: '/WEB-INF/data/$1'
},
{
    reg: /^\/pkg\/(.*\.(css|js))$/i,
    isMod: true,
    release: '${statics}/${namespace}/pkg/$1',
    url: '${webname}/${namespace}/pkg/$1'
}].concat(fis.config.get('roadmap.path')));

fis.config.merge({
    webname: '',
    // statics: '',
    namespace: 'common',
    roadmap: {
        ext: {
            less: 'css'
        }
    },
    settings: {
        spriter: {
            csssprites: {
                //图之间的边距
                margin: 5
            }
        },
        optimizer: {
            'png-compressor': {
                type: 'pngquant' //default is pngcrush
            }
        },
        postpackager: {
            simple: {
                autoCombine: true
            }
        }
    },
    pack: {
        'pkg/common.js': [
            '/widget/ui/template/template.js',
            '/widget/ui/iscroll/iscroll4.js',
            /^\/widget\/ui\/zepto\/.*\.js$/i
            // '/widget/ui/fastclick/fastclick.js',
        ]
    },
    modules: {
        parser: {
            less: 'less'
        },
        optimizer: {
            tpl: 'html-compress'
        },
        spriter: 'csssprites',
        postpackager: 'simple'
    },
    deploy: {
        // 开发用
        work: [{
            receiver: 'http://10.2.3.24:8999/receiver',
            from: '/WEB-INF/views',
            to: workPath + 'ad-ui/WEB-INF/classes'
        },{
            receiver: 'http://10.2.3.24:8999/receiver',
            from: '/static',
            to: workPath + 'ad-ui/WEB-INF/classes'
        },{
            receiver: 'http://10.2.3.24:8999/receiver',
            from: '/WEB-INF/data',
            to: workPath + 'ad-ui/WEB-INF/'
        },{
            receiver: 'http://10.2.3.24:8999/receiver',
            from: '/WEB-INF/config',
            to: workPath + 'ad-ui/WEB-INF/'
        }],
        // work: [{
        //     receiver: 'http://10.2.3.24:8999/receiver',
        //     from: '/',
        //     to: workPath + 'ad-ui/'
        // }],
        local: [{
            from: '/',
            to: '/Library/Tomcat/webapps/ad-demo-1/'
        }]
    }
});

产出的map:

{
  "res": {
    "common:page/layout/base.vm": {
      "uri": "/common/page/layout/base.vm",
      "type": "vm",
      "extras": {
        "isPage": true
      }
    },
    "common:static/js/mod.js": {
      "uri": "/common/js/mod_1c8526c.js",
      "type": "js"
    },
    "common:widget/conf/conf.vm": {
      "uri": "/common/widget/conf/conf.vm",
      "type": "vm"
    },
    "common:widget/css-base/css-base.vm": {
      "uri": "/common/widget/css-base/css-base.vm",
      "type": "vm"
    },
    "common:widget/css-base/layout.less": {
      "uri": "/common/widget/css-base/layout_e12e54a.css",
      "type": "css"
    },
    "common:widget/css-base/reset.less": {
      "uri": "/common/widget/css-base/reset_d371a04.css",
      "type": "css"
    },
    "common:widget/css-base/tool.less": {
      "uri": "/common/widget/css-base/tool_84dd714.css",
      "type": "css"
    },
    "common:widget/css-base/var.less": {
      "uri": "/common/widget/css-base/var_01e1968.css",
      "type": "css"
    },
    "common:widget/ui/fastclick/fastclick.js": {
      "uri": "/common/widget/ui/fastclick/fastclick_039fbf8.js",
      "type": "js"
    },
    "common:widget/ui/iscroll/iscroll4.js": {
      "uri": "/common/widget/ui/iscroll/iscroll4_1cd3fd8.js",
      "type": "js",
      "pkg": "common:p0"
    },
    "common:widget/ui/iscroll/iscroll5.js": {
      "uri": "/common/widget/ui/iscroll/iscroll5_12f7959.js",
      "type": "js"
    },
    "common:widget/ui/template/template.js": {
      "uri": "/common/widget/ui/template/template_e622ab1.js",
      "type": "js",
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.1.1.3.js": {
      "uri": "/common/widget/ui/zepto/zepto.1.1.3_5a713c5.js",
      "type": "js",
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.assets.js": {
      "uri": "/common/widget/ui/zepto/zepto.assets_b934fdc.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.callbacks.js": {
      "uri": "/common/widget/ui/zepto/zepto.callbacks_9a2cc25.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.data.js": {
      "uri": "/common/widget/ui/zepto/zepto.data_7413b6a.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.deferred.js": {
      "uri": "/common/widget/ui/zepto/zepto.deferred_8183064.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.fx.js": {
      "uri": "/common/widget/ui/zepto/zepto.fx_0769730.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.fx_methods.js": {
      "uri": "/common/widget/ui/zepto/zepto.fx_methods_83a7841.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.js": {
      "uri": "/common/widget/ui/zepto/zepto_75ddf81.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js",
        "common:widget/ui/zepto/zepto.touch.js",
        "common:widget/ui/zepto/zepto.selector.js",
        "common:widget/ui/zepto/zepto.callbacks.js",
        "common:widget/ui/zepto/zepto.stack.js",
        "common:widget/ui/zepto/zepto.data.js",
        "common:widget/ui/zepto/zepto.deferred.js",
        "common:widget/ui/zepto/zepto.assets.js",
        "common:widget/ui/zepto/zepto.fx.js",
        "common:widget/ui/zepto/zepto.fx_methods.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.selector.js": {
      "uri": "/common/widget/ui/zepto/zepto.selector_42241b0.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.stack.js": {
      "uri": "/common/widget/ui/zepto/zepto.stack_3f78d33.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    },
    "common:widget/ui/zepto/zepto.touch.js": {
      "uri": "/common/widget/ui/zepto/zepto.touch_24027e6.js",
      "type": "js",
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js"
      ],
      "pkg": "common:p0"
    }
  },
  "pkg": {
    "common:p0": {
      "uri": "/common/pkg/common_30cc44f.js",
      "type": "js",
      "has": [
        "common:widget/ui/template/template.js",
        "common:widget/ui/iscroll/iscroll4.js",
        "common:widget/ui/zepto/zepto.1.1.3.js",
        "common:widget/ui/zepto/zepto.assets.js",
        "common:widget/ui/zepto/zepto.callbacks.js",
        "common:widget/ui/zepto/zepto.data.js",
        "common:widget/ui/zepto/zepto.deferred.js",
        "common:widget/ui/zepto/zepto.fx.js",
        "common:widget/ui/zepto/zepto.fx_methods.js",
        "common:widget/ui/zepto/zepto.touch.js",
        "common:widget/ui/zepto/zepto.selector.js",
        "common:widget/ui/zepto/zepto.stack.js",
        "common:widget/ui/zepto/zepto.js"
      ]
    }
  }
}

页面中的resourceMap:

{
  "pkg": {
    "common:p0": {
      "has": [
        "common:widget/ui/template/template.js",
        "common:widget/ui/iscroll/iscroll4.js",
        "common:widget/ui/zepto/zepto.1.1.3.js",
        "common:widget/ui/zepto/zepto.assets.js",
        "common:widget/ui/zepto/zepto.callbacks.js",
        "common:widget/ui/zepto/zepto.data.js",
        "common:widget/ui/zepto/zepto.deferred.js",
        "common:widget/ui/zepto/zepto.fx.js",
        "common:widget/ui/zepto/zepto.fx_methods.js",
        "common:widget/ui/zepto/zepto.touch.js",
        "common:widget/ui/zepto/zepto.selector.js",
        "common:widget/ui/zepto/zepto.stack.js",
        "common:widget/ui/zepto/zepto.js"
      ],
      "type": "js",
      "url": "/common/pkg/common_30cc44f.js"
    }
  },
  "res": {
    "ad:widget/detail/groupon-info/groupon-info-async.js": {
      "deps": [
        "common:widget/ui/zepto/zepto.js",
        "common:widget/ui/iscroll/iscroll4.js"
      ],
      "url": "/ad/widget/detail/groupon-info/groupon-info-async_5f139c8.js"
    },
    "ad:widget/detail/groupon-recommend/groupon-recommend-async.js": {
      "deps": [
        "common:widget/ui/zepto/zepto.js"
      ],
      "url": "/ad/widget/detail/groupon-recommend/groupon-recommend-async_1181890.js"
    },
    "common:widget/ui/zepto/zepto.js": {
      "deps": [
        "common:widget/ui/zepto/zepto.1.1.3.js",
        "common:widget/ui/zepto/zepto.touch.js",
        "common:widget/ui/zepto/zepto.selector.js",
        "common:widget/ui/zepto/zepto.callbacks.js",
        "common:widget/ui/zepto/zepto.stack.js",
        "common:widget/ui/zepto/zepto.data.js",
        "common:widget/ui/zepto/zepto.deferred.js",
        "common:widget/ui/zepto/zepto.assets.js",
        "common:widget/ui/zepto/zepto.fx.js",
        "common:widget/ui/zepto/zepto.fx_methods.js"
      ],
      "pkg": "common:p0",
      "url": "/common/widget/ui/zepto/zepto_75ddf81.js"
    }
  }
}

页面现象:
image
。。请问是否是所有的js资源只要是使用require都应该在resourceMap中的res字段中有对应的键。否则会出现类似这种common:widget/ui/zepto/zepto.assets.js请求,导致查找不到相应的res。进而导致查找不到相应的pkg?
请问是我配置的问题吗?如何解决。谢谢。

模板继承优化。

目前 velocity 模板继承只实现了扩充功能,被继承模板中的 block directive 如果有内容不会被清空,而是扩充进去。

目前有同学反应,应该支持覆盖方案,就是原来的内容完全被清除,然后采用新内容。

如是我打算加两个 diretive

  1. #override("id") content ... #end
    完全覆写layout中的block
  2. #remove("id")
    删除layout中的block

后端使用java,部署到tomcat可以使用extends等标签读取模板,但使用内嵌tomcat服务器就不行

From @sxpujs on April 12, 2015 8:46

我的开发环境是:Spring 4.1.3 + Spring Boot + Jello, 将应用打包成war发布到tomcat是可以正常使用的,但打包成jar包,使用内嵌的tomcat启动时读取不到模板文件,请哪位大神看下是什么原因?

比如说有个recommend.vm,内容如下:

#extends("/ad/page/base/base.vm")
    #block("body")
        #widget("ad:widget/recommend/sort/sort.vm")
        #widget("ad:widget/recommend/recommend/recommend.vm")
    #end
#end

但显示该页面时会出错,错误日志如下:

2015-04-12 16:18:08.834 ERROR 8408 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/ad/page/base/base.vm'] with root cause

org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/ad/page/base/base.vm'
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.directive.Parse.render(Parse.java:197)
at com.baidu.fis.velocity.directive.AbstractInclude.render(AbstractInclude.java:237)
at com.baidu.fis.velocity.directive.Extends.doRender(Extends.java:100)
at com.baidu.fis.velocity.directive.Extends.render(Extends.java:47)
at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:207)
at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
at org.apache.velocity.Template.merge(Template.java:356)
at org.apache.velocity.Template.merge(Template.java:260)
at org.springframework.web.servlet.view.velocity.VelocityView.mergeTemplate(VelocityView.java:517)
at org.springframework.web.servlet.view.velocity.VelocityView.doRender(VelocityView.java:462)
at org.springframework.web.servlet.view.velocity.VelocityView.renderMergedTemplateModel(VelocityView.java:292)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

Copied from original issue: fex-team/fis#431

jello 中的velocity模板问题

为什么用了velocity反而解析十几秒才返回页面??原JSP解析两秒多换成velocity反而解析的更慢了。。而且经过测试发现dataSource经常死掉。我只是单机测试。没换jello前 无任何问题。

优化 #script #style directive 让其支持外链。

目前引用 js 和 css 都是通过 #require("xxx:xxx/path.js")#require("xxx:xxx/path.css")。如果此处路径是一个能在 source map 中找到的 ID 没有问题,但是如果用户需要引入一个不在 source map 中的 uri,则会报错。

所以这里通过添加 #script #style 引入外部 uri 资源功能来解决此问题。如:

#script("/framework/jquery/jquery.js")#end

关于jello输出的html代码

css和js总是粘在一起,html标签也不是很好看
4gb0wk15_ni ey o4 4 ow0

不知道有没有什么方法让html代码格式代,或者压缩一下

jello开发的模板页面 连续刷新页面 出现http status 500的情况

请问是否是jello在处理并发访问时存在问题?

HTTP Status 500 - Request processing failed; nested exception is java.util.ConcurrentModificationException

type Exception report

message Request processing failed; nested exception is java.util.ConcurrentModificationException

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.util.ConcurrentModificationException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause

java.util.ConcurrentModificationException
java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
java.util.ArrayList$Itr.next(ArrayList.java:831)
org.apache.velocity.app.event.EventHandlerUtil.iterateOverEventHandlers(EventHandlerUtil.java:440)
org.apache.velocity.app.event.EventHandlerUtil.callEventHandlers(EventHandlerUtil.java:416)
org.apache.velocity.app.event.EventHandlerUtil.includeEvent(EventHandlerUtil.java:246)
org.apache.velocity.runtime.directive.Parse.render(Parse.java:156)
com.baidu.fis.velocity.directive.AbstractInclude.render(AbstractInclude.java:52)
com.baidu.fis.velocity.directive.Extends.doRender(Extends.java:124)
com.baidu.fis.velocity.directive.Extends.render(Extends.java:51)
org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:207)
org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
org.apache.velocity.Template.merge(Template.java:356)
org.apache.velocity.Template.merge(Template.java:260)
org.springframework.web.servlet.view.velocity.VelocityView.mergeTemplate(VelocityView.java:517)
org.springframework.web.servlet.view.velocity.VelocityView.doRender(VelocityView.java:462)
org.springframework.web.servlet.view.velocity.VelocityView.renderMergedTemplateModel(VelocityView.java:291)
org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.57 logs.

VM 中的图片路径中的变量不能正确替换, 有什么办法解决吗?

<div id="slides" class="slides slider-container">
  <img src="../res/project/outlet/images/home/ad_large_1.png">
  <img src="../res/project/outlet/images/home/ad_large_2.png">
</div>
#foreach($idx in [1..4])
  <div class="goods-card">
    <img src="../res/project/outlet/images/home/ad_small_${idx}.png">
  </div>
#end

经jello 处理后, 变成:

<div id="slides" class="slides slider-container">
  <img src="/static/project/outlet/images/home/ad_large_1.png">
  <img src="/static/project/outlet/images/home/ad_large_2.png">
</div>
<div class="goods-cards">
  #foreach($idx in [1..4])
    <div class="goods-card">
      <img src="../res/project/outlet/images/home/ad_small_${idx}.png">
    </div>
  #end
</div>

也就是说, 没有使用变量的两个图片, 能够正确进行替换, 但是下面路径中包含了变量的图片, 却没有正确替换. 这要如何解决呢?

fis-conf.js 中roadmap 的配置为:

fis.config.set('roadmap.path', [

    {
        reg: /^\/widget\/(.*\.(?:vm))$/i,
        isMod: true,
        url: '/widget/$1',
        release: '/xiangin/templates/widget/$1'
    },

    {
        reg: /^\/res\/lib\/(.*)$/i,
        release: '${statics}/lib/$1'
    },

    {
        reg: /^\/res\/plugins\/(.*\.css)$/i,
        usePostprocessor: false,
        release: '${statics}/plugins/$1'
    },

    {
        reg: /^\/res\/plugins\/(.*)$/i,
        release: '${statics}/plugins/$1'
    },

    {
        reg: /^\/res\/(.*\.(?:png|gif|jpg|jpeg))$/i,
        release: '${statics}/$1'
    },

    {
        reg: /^\/res\/(.*)$/i,
        isMod: true,
        release: '${statics}/$1'
    }
].concat(fis.config.get('roadmap.path')));

mod.js跨模块引用报错

报错信息如下:(诡异的是,注释掉页面引用的一个widge就没有问题,难道有什么冲突,)

Uncaught TypeError: object is not a function content.js:56
init content.js:62
(anonymous function) mod.js:128
next mod.js:158
(anonymous function) mod.js:74
callDep mod.js:156
(anonymous function) mod.js:158
(anonymous function)

求解

components组件跨模块引用问题

下了一个jello的demo,fis-conf.js的配置引用compass的路径是fis.config.set('settings.parser.sass.include_paths', [
'./components/compass-mixins'
])

在scss文件里引用是用 “@import "compass/css3" “;
现在我想把components模块放到common里面,供其他的模块引用,
试了/@require "home:components/compass/css3";/,@import(xxxx.scss?__inline)等方法,编译不通过,

请问如何跨模块的引用components

加CDN前缀后能否去掉static

默认的静态资源目录是static,所以我如果加了domain过后,引用路径就会变成cdn.a.com/static/xxx,也就是我的cdn目录也需要这个static目录,感觉加深一层目录深度不舒服,不知道有没有方法可以避免?

Velocity 中如何快速实现 json_encode 功能

在尝试用 jello 开发项目的时候遇到了一个问题,也有不少同学也反应过,就是如何快速的实现 json_encode 功能。

很多时候,都需要把后端的数据 object 转换成 json 格式给 js 使用。但是 velocity 里面又没有对应的方法。

如是今天研究了一把,目前想到了一个比较合理的方法就是通过 velocity tools 提供,暂时先把方法贴出来,后续补充到 jello 的 jar 里面去。

实现步骤

新建一个 tool 类

package com.baidu.fis.velocity.util;

import com.alibaba.fastjson.JSON;
import org.apache.velocity.tools.config.DefaultKey;

@DefaultKey("jello")
public class jelloTool {
    public static String jsonEncode(Object obj) {
        return JSON.toJSONString(obj);
    }
}

在 spring 的配置中启用

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
    <property name="cache" value="true"/>
    <property name="prefix" value=""/>
    <property name="suffix" value=".vm"/>
    <property name="exposeSpringMacroHelpers" value="true"/>
    <property name="contentType" value="text/html;charset=UTF-8" />
    <property name="attributesMap">
        <map>
            <entry key="esc"><bean class="org.apache.velocity.tools.generic.EscapeTool"/></entry>
            <entry key="render"><bean class="org.apache.velocity.tools.generic.RenderTool" /> </entry>
            <entry key="jello"><bean class="com.baidu.fis.velocity.util.jelloTool" /> </entry>
        </map>
    </property>
</bean>

这样就可以在模板中这么使用。

<script>
    var user = $jello.jsonEncode($user);
    console.log(user);
</script>

请教一个问题

我看到你们用这种写法
require("example:widget/widgetA/widgetA.js");
require("common:widgetA/widgetA.js");

请问:
common:
example:
这种写法有什么用,有什么好处,怎么使用
谢谢了!

发现一个pack问题

fis.config.set('pack',{});

在配置打包的时候,
比如我把3个css打包成一个,这是没问题的,
但是,我请求另一个页面,只用到这3个css中的其中一个,
于是它还是使用这个打包后的css

这个如何解决

建议不要压缩map文件

提一个小建议,jello release -p后不要压缩生成的map json文件,这样比较方便查看。

Ubuntu下无法安装插件fis-parser-sass,请教下怎样才能安装阿?

npm http GET https://registry.npmjs.org/fis-parser-sass
npm http 200 https://registry.npmjs.org/fis-parser-sass
npm http GET https://registry.npmjs.org/fis-parser-sass/-/fis-parser-sass-0.3.7.tgz
npm http 200 https://registry.npmjs.org/fis-parser-sass/-/fis-parser-sass-0.3.7.tgz
npm http GET https://registry.npmjs.org/fis-sass
npm http 304 https://registry.npmjs.org/fis-sass
npm http GET https://registry.npmjs.org/chalk
npm http GET https://registry.npmjs.org/step/0.0.5
npm http GET https://registry.npmjs.org/nan
npm http 304 https://registry.npmjs.org/chalk
npm http 304 https://registry.npmjs.org/nan
npm http 304 https://registry.npmjs.org/step/0.0.5
npm http GET https://registry.npmjs.org/ansi-styles
npm http GET https://registry.npmjs.org/escape-string-regexp
npm http GET https://registry.npmjs.org/has-ansi
npm http GET https://registry.npmjs.org/strip-ansi
npm http GET https://registry.npmjs.org/supports-color
npm http 304 https://registry.npmjs.org/strip-ansi
npm http 304 https://registry.npmjs.org/supports-color
npm http 304 https://registry.npmjs.org/ansi-styles
npm http 304 https://registry.npmjs.org/has-ansi
npm http 304 https://registry.npmjs.org/escape-string-regexp
npm http GET https://registry.npmjs.org/ansi-regex
npm http GET https://registry.npmjs.org/ansi-regex
npm http 304 https://registry.npmjs.org/ansi-regex
npm http 304 https://registry.npmjs.org/ansi-regex

[email protected] install /usr/local/lib/node_modules/fis-parser-sass/node_modules/fis-sass
node build.js

Downloading http://fisstatic.duapp.com/addons/fis-sass/3.1.0/linux-x64/0.9.11/binding.node ...
Received 512K...
Received 1030K...
Received 1543K...
Received 1753K total.
Test failed!
gyp: /data/qqli/.node-gyp/0.10.26/common.gypi not found (cwd: /usr/local/lib/node_modules/fis-parser-sass/node_modules/fis-sass) while reading includes of binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: gyp failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:337:16)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:797:12)
gyp ERR! System Linux 2.6.38-10-generic
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /usr/local/lib/node_modules/fis-parser-sass/node_modules/fis-sass
gyp ERR! node -v v0.10.26
gyp ERR! node-gyp -v v0.12.2
gyp ERR! not ok
Build failed
npm ERR! [email protected] install: node build.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the fis-sass package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node build.js
npm ERR! You can get their info via:
npm ERR! npm owner ls fis-sass
npm ERR! There is likely additional logging output above.

npm ERR! System Linux 2.6.38-10-generic
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "-g" "fis-parser-sass"
npm ERR! cwd /data/personal/mydata/jello
npm ERR! node -v v0.10.26
npm ERR! npm -v 1.4.3
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /data/personal/mydata/jello/npm-debug.log
npm ERR! not ok code 0

如何异步获取 widget 目录下的组件?

假设有以下的目录:

-- page
    -- index
        -- index.vm
    -- login
        -- index.vm
-- widget
    -- login
        -- index.css
        -- index.js
        -- index.vm

其中 widget/login是一个具有完整登录业务的组件。那么如果我们只需在登录页面page/login/index.vm引入这个组件就可以,代码如下:

.....
#widget('widget/login/index.vm')
.....

那么,假如说在首页page/index/index.vm里,有一个按钮会弹出一个登录弹框,那么怎么将这个登录组件引入呢?page/index/index.vm代码如下

.....
## 按钮这里如何 ajax 异步引入 `widget/login` 内容??
<button>登录弹框</button>
#script()
document.querySelector('button').onclick = function () {
       // 弹框登录业务,如何引入??
 }
#end
.....

目前想到的方案有:
1)在page/index/index.vm也引入登录 widget 文件,默认隐藏,在点击按钮时,将其显示出来
2)ajax 请求这个登录 widget 文件,让后台输出 html,然后在 append 页面里

jello 里有相关的解决方案嘛?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.