乐鱼app成为大巴黎赞助商

乐鱼app成为大巴黎赞助商举行“同心喜迎二十大 传承中华优秀传统文化”中国古代文化常识竞赛             2023年七年级招生简章             凝望经典赏别样人生 创新表达树文化自信——河池市乐鱼app成为大巴黎赞助商高一年级举行课本剧展演活动             守护青春,护航成长 ——宜州区一中举行法制教育报告会             以赛促教展师风 凝心聚力踏征程 ——乐鱼app成为大巴黎赞助商开展教师教学技能大赛             辩以明思,坐而论道 ——记宜州区一中2024届高二辩论赛             巧借他山石,精雕“三新”玉 ——乐鱼app成为大巴黎赞助商教师赴湖南考察学习交流活动             2023年春季学期“世界地球日”知识讲座成功举办             乐鱼app成为大巴黎赞助商开展防溺水教育活动 全力筑牢生命安全防线             法治教育进校园 护航青春助成长            

DoraCMS

您现在的位置是:首页>文档内容页

文档详情

乐鱼app成为大巴黎赞助商:第9天response 响应渲染 —动态渲染插件开发

doramart 2023-06-02 23:28:56 技术文档225908
下面列出view插件源代码,然后对其进行讲解。lib/view.js源代码

乐鱼app成为大巴黎赞助商:动态渲染插件开发

下面列出view插件源代码,然后对其进行讲解。

lib/view.js源代码

var fs = require("fs"),
    path = require("path");

// 过滤 \r\n
function filterRN(s){
    s = s.replace("\'","\"");
    s = s.replace(/\n/g,"\\n");
    s = s.replace(/\r/g,"\\r");
    return "result += \'"+s+"\';\n\r";
}    

module.exports = function(viewPath){

    var viewCache = {}
    fs.readdir(viewPath, function(err,files){

        files.forEach(function(fn){
            var filePath = path.join(viewPath,fn);
            fs.readFile(filePath,function(err,data){

                var str = data.toString();                
                var buf = [];
                buf.push('var result = "";')
                var htmlPart= "";
                for(var i=0,len = str.length;i<len;){

                    if(str.slice(i,i+2) === "<%"){

                        var end =  str.indexOf("%>",i);

                        var jsPart = str.slice(i+2,end);

                        i = end+2;
                        buf.push(filterRN(htmlPart));
                        htmlPart = "";

                        if(jsPart.slice(0,1) === "="){
                            buf.push("\r\nresult += "+jsPart.slice(1)+";\r\n")
                        }else{
                            buf.push("\r\n"+jsPart+"\r\n");
                        }

                    }else{
                        htmlPart += str.slice(i,i+1);
                        i += 1;
                    }

                }

                buf.push(filterRN(htmlPart));
                buf.push("return result;")
                viewCache[fn] = new Function("locals",buf.join(""));

            });
        })
    })

    return function(req,res,next){
        res.view = function(fileName,locals){
            res.write(viewCache[fileName](locals));
            res.end();
        }
        next();
    }

}

这个插件的原理,上节分析过了,下面对细节进行讲解。插件用到了核心库的两个模块 fspath,fs都很熟悉了,path.join方法是把字符串连接为一个完整目录的方法,可以参考附录。viewCache用来储存模板页面Function形式的。插件在调用app.use(view(viewPath))时,会读取这个目录下的全部文件,然后转换为javascript Function对象,保存到viewCache之中。

转换一个模板文件的方法是从头读。庇龅<%时会通过indexOf找到配对的%>,然后抽离出中间的javascript代码,保存到buf中。而启动它部分都转换为字符串对象result += ...... ,接着添加return result;字符串。而这些字符串储存在 var buf = [];中,在最后通过 buf.join("')把这些字符串数组合并为一个字符串,就构成了view函数体,最后通过viewCache[fn] = new Function("locals",buf.join("")); 转换为javascript Function对象保存到viewCache中。

filterRN函数是用来过滤 \n\r 并且把它们转换为 \\n \\r 形式,目的是保证函数体能正确执行。因为如果不过滤,就会出现以下的函数体:

result += "
   abc
"

这是错误的,javascript不支持这种写法,所以通过转换后就会得到如下形式:

result += "\r\n abc \r\n";

代码不是太复杂,仔细分析后就能理解。重要的是自己要动手去开发,想一想如果模板文件不是<%%>这种形式,换成其他的写法应该如何做这个插件,比如模板文件是缩进写法等等。当然转换后的形式应该都是javascript Function对象形式。

最后,我们在index.js文件中加入以下代码,view插件就算告一段落了。

exports.view = require("./lib/view");

下一节,将用一个实例进行说明。

文章评论

取消回复
登录 参与评论

评论列表(

乐鱼app成为大巴黎赞助商