博客作出來的時候就想要把一些欄目和文章頁都靜態化處理,當時沒啥時間搞,就一直沒去弄。可是最近的工做就是作網站,用cms快速搭出了幾個網站,cms搭建網站是真的方便啊 若是沒有須要二次開發實現的功能,那基本不須要寫後端代碼的。並且作出來的還不錯,怪不得看不少博主都是用cms搭建的博客。 我是用的FreeCMS,展現層就有用Free Marker來作。 而後就參考這個cms的源碼 把本身博客的文章頁靜態化了下。css
原文鏈接:ZJBLOGhtml
靜態化主要是爲了提升網頁打開的速度,而後還有利於SEO,更容易被搜索引擎識別收錄,並且比較穩定和安全。java
free marker靜態化原理是用模板+數據模型=輸出html網頁。jquery
freemarker並不關心數據的來源,只是根據模板的內容,將數據模型在模板中顯示並輸出文件(一般爲html,也能夠生成其它格式的文本文件)web
首先引入jar包ajax
Free marker的jar包和文檔數據庫
連接:https://pan.baidu.com/s/1GZNvnOT6wbb2S6646c7cSQ 密碼:q0af後端
maven依賴安全
<!-- freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
代碼app
根據模板文件和數據模型建立html的方法
private void createHtml(String templetPath, String siteInfoPath, HashMap<String, Object> map) throws Exception { // ①建立配置對象(建立一個Configuration對象,直接new一個對象。構造方法的參數就是freemarker對於的版本號。) Configuration cfg = new Configuration(Configuration.getVersion());// 注意:這裏須要傳遞一個版本 // ②讀取模板文件夾 cfg.setDirectoryForTemplateLoading(new File(templetPath));// 設置要加載的模板文件的路徑,這裏的templetPath就是模板的路徑webapp/templet/ // ③設置模板的編碼格式 cfg.setDefaultEncoding("UTF-8"); // ④獲取模板對象 Template template = cfg.getTemplate("info.html");// info.html是模板名稱 // ⑥將模板和數據模型合併 --> 輸出模板,生成文件 // 靜態頁面路徑 File htmlFile = new File(siteInfoPath); //siteInfoPath是靜態化生成的html存放的路徑,webapp/site/info/2019-11-30(文章日期)/文章id.html(根據本身的須要來設置) if (!htmlFile.getParentFile().exists()) { htmlFile.getParentFile().mkdirs(); //文章不存在則建立 } PrintWriter pw = new PrintWriter(htmlFile); template.process(map, pw);// 合併 map:數據模型 pw:輸出流對象 map中存的是模板文件中須要的數據文章列表等,在模板文件中用${..}獲取,可參考free marker文檔 pw.close();// 關閉流 }
靜態化文章頁的方法
/** * 靜態化文章頁 * * @param articleId * @throws IOException */ @RequestMapping({"/toCrea****"}) public String toCreate****(HttpServletRequest request, Long articleId) throws Exception { LOGGER.info("靜態化文章方法開始"); //查詢要靜態化的文章信息 Article article = new Article(); article.setArticleId(articleId); Article articleDetail = articleService.selectByKeyWords(article); //文章發佈的時間,用於將靜態化的文章網頁放在對應時間的文件夾中 String articleTime = Tools.getStrDateTime(articleDetail.getCreationtime(), "yyyy-MM-dd"); // 給文章添加訪問路徑(發佈一篇文章後靜態化該文章,靜態化時將該文章的靜態化後路徑添加至數據庫) String pageUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/site/info" + articleId + ".html"; articleDetail.setPageUrl(pageUrl); articleService.upArticle(articleDetail); // 建立數據模型(這裏使用map類型) --[數據模型能夠是List、Map對象 注意:Map類型的key必須是String類型] HashMap<String, Object> map = new HashMap<>(); map.put("contextPathNo", request.getSession().getServletContext().getContextPath());// 項目名稱,用於生成後html頁面的靜態資源調用css,img等 // 文章信息 ......//其餘信息代碼省略。。。 map.put("info", articleDetail); ...... //模板所在的路徑 String templetPath = request.getSession().getServletContext().getRealPath("/templet"); //靜態化生成的html路徑 String siteInfoPath = request.getSession().getServletContext() .getRealPath("/site/info/" + articleTime + "/" + articleId + ".html"); createHtml(templetPath, siteInfoPath, map); return "success"; }
模板文件info.html(省略了不少代碼,僅做爲示例)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>${info.articleTitle }</title> <link href="${contextPathNo}/css/details.css" rel="stylesheet"> <script src="${contextPathNo}/js/jquery-1.7.2.min.js"></script> </head> <body> <!-- 文章信息 --> <h2 class="c_titile" style="font:'宋體', Arial, Helvetica, sans-serif;color: #756F71">${info.articleTitle}</h2> <p class="box_c" style="font: 12px '宋體', Arial, Helvetica, sans-serif;color: #756F71"> <span class="d_time">發佈時間:${info.creationtime?string('yyyy-MM-dd hh:mm') }</span> <!-- ?string將date類型時間轉爲字符串顯示--> <span>編輯:${info.articleAuthor}</span> 閱讀:<span id='ajaxInfoClickSpan'><img src='${contextPathNo}/images/ajax-loader.gif'/></span><!-- 文章點擊量 須要動態展現 --> <input type="hidden" value="${info.articleId?c}" id="articleIdinit"><!-- ?c將long類型文章id正常顯示,不加?c會被,分割--> </p> <ul class="infos">${info.articleDetail } </ul> <!-- 其餘的例如文章列表、判斷等 --> <#if (info.parent==333)> <a class="n2" href="${contextPathNo}/toSharesss">程序人生</a> </#if> <!-- 非空判斷 frm沒有null--> <#if upArticle??> <p> 上一篇:<a href="${contextPathNo}/toDetail}">${upArticle.articleTitle}</a> </p> </#if> <!-- 遍歷列表,if else 。獲取長度須要?使用.沒用--> <ul class="rank"> <#list newTimeArticleList as newList> <#if (newList.articleTitle?length>16)> <li><a href="${contextPathNo}/toDetail" title="${newList.articleTitle }" target="_blank">${newList.articleTitle?substring(0,16)}...</a></li> <#else> <li><a href="${contextPathNo}/toDetail" title="${newList.articleTitle }" target="_blank">${newList.articleTitle}</a></li> </#if> </#list> </ul> <!-- 大概的模板,更多的內容參考文檔--> </body> </html>
這樣就能根據模板來生成一個html靜態網頁了。
須要注意的是,有些動態展現的內容 是不能直接靜態化的,好比 文章的點擊數和 右側的最熱文章,最新文章,底部的上一篇下一篇等。。。
暫時沒有的解決方式 我就用了ajax來加載的。。