网站的文章模块是怎么实现的?

比如加载一篇文章,是先写好页面模板再加载文字还是在发表文章的时候后台直接生成一个页面?
我想到的实现方法是用url存储文章序列号,然后不管输入什么url参数都返回一个固定模板,然后用js获取url参数请求后台返回文章内容,再用js把文章加载上去,但我看很多网站文章源码好像都是直接写在里面的,那就是发表文章时直接生成的页面吗?或者是返回请求的时候后台获取数据库文章加载到模板里的?

你可以用一下CMS内容管理系统
一、显示文章列表
对文章列表进行展示的时候可以使用GridManager表格插件,能够更加方便的展示列表数据,不需要像传统的方式进行拼接或使用jstl+el表达式进行拿值,而且传统的方式太麻烦,也很容易拼接错误。
columnData里面的key值就是文章信息实体类中对应的字段,text为每列数据对应的标题名。通过ajax向后台发送获取所有的文章信息的请求,前台拿到文章的所有信息就可以让数据在列表中展示出来。
注意:GridManager表格插件接收后台返回的数据格式必须是data和totals的格式,这个时候后台可以返回一个Map<String,Object>格式或者是将data和totals单独封装成一个类然后后台直接返回一个实体类对象。

前台页面列表展示:

<!-- 存放table列表 -->
<table id='table-demo-ajaxPageCode'></table>
1
2
document.querySelector('#table-demo-ajaxPageCode').GM({
    gridManagerName: 'demo-ajaxPageCode',
    ajaxData: '/system/article/findAll',
    ajaxType: 'POST',
    supportAjaxPage: true,//是否支持分页
    sizeData:[5,10,15,20],//每页显示条数的下拉框
    pageSize:5,//初始时每页显示的条数
    currentPageKey:'currentPage',//当前页的键值
    pageSizeKey:'pageCount',//每页条数的键值
    height:"100%",//表格显示的高度为百分百
    columnData: [
        {
            key: 'title',
            text: '标题',
            align: 'center'//文字居中显示
        },{
            key: 'url',
            text: '地址'
        },{
            key: 'type',
            text: '分类',
            template: function(cell, row, index, key){
                return cell.name;
            },
            align: 'center'
        },{
            key: 'clickCount',
            text: '点击量',
            align: 'center'
        },{
            key:'enable',
            text:'状态',
            template: function(cell, row, index, key){
                return cell?"<font color='blue'>启用</font>":"<font color='red'>禁用</font>";
            },
            align: 'center'
        },{
            key: 'createDate',
            text: '创建时间',
            align: 'center'
        },{
            key: 'id',
            text: '操作&nbsp;&nbsp;<a href="javascript:;" id="add">添加 </a>',
            width: '100px',
            fixed: 'right',
            align: 'center',
            template: function(cell, row, index, key){
                //row能够获取每行对象的所有信息
                var data=JSON.stringify(row);
                return "<a href='javascript:;' data-id='"+cell+"' class='del'>删除 </a>&nbsp;&nbsp;"+"<a href='javascript:;' id='edit' data-row='"+data+"' class='edit'>修改</a>";
            }
        }
    ],
});


二、文章信息列表分页的实现
使用GridManager自带的分页功能,为了实现分页效果,我们只需要配置分页相关的属性。
a. supportAjaxPage: true,//显示分页条
b. sizeData:[5,10,15,20],//每页显示条数的下拉框
c. pageSize:5,//初始时每页显示的条数
d. currentPageKey:‘currentPage’,//当前页的key键值
e. pageSizeKey:‘pageCount’,//每页条数的key键值
后台可以将分页的属性currentPage和pageCount单独封装成一个类,然后后台通过对象接收分页的信息。后台对查询的所有的数据进行分页查询就可以实现分页功能。
分页实体类:

public class BaseQuery {
//当前页码
private Integer currentPage;

//每页显示条数
private Integer pageCount;

//每页的起始索引
public Integer getBegin(){
    return (currentPage-1)*pageCount;
}

public Integer getCurrentPage() {
    return currentPage;
}

public void setCurrentPage(Integer currentPage) {
    this.currentPage = currentPage;
}

public Integer getPageCount() {
    return pageCount;
}

public void setPageCount(Integer pageCount) {
    this.pageCount = pageCount;
}

@Override
public String toString() {
    return "BaseQuery [currentPage=" + currentPage + ", pageCount=" + pageCount + "]";
}

}

分页的实现:(begin属性的值是直接从封装的分页实体类里面的getBegin方法获取的该属性的值)

<select id="findAll" resultType="Article" parameterType="ArticleQuery">
    select * from t_article limit #{begin},#{pageCount}
</select>

三、页面静态化的实现
页面静态化的目的:之所以要实现页面的静态化,是因为静态页面的加载速度比动态页面的加载速度快,动态页面会进行数据库的操作需要获取连接,需要编译,花费的时间较长。
实现的方法:使用freemarker技术生成对应的静态页面。
页面静态化技术编程步骤:
a. 导入相关的freemarker的jar包。
b. 获取模板对象。
c. 准备数据。(只能是map或实体类对象)
d. 生成静态资源(template.process())
e. 创建以ftl结尾的模板。
静态化页面需要相关的开关,所以我们可以在添加和修改文章信息的信息就生成相应的静态页面。
静态页面的生成会在很多地方被重复使用,可以将其封装成工具类,不仅提高代码的重用性,同时还能够提高开发效率。
FreeMarkUtil 工具类:

public class FreeMarkUtil {
    public static String createTemplate(String loadPath,String templateName,Object data,String suffix){
        FileWriter out = null;
        try {
            //获取Configuration对象 -- 为了获取模板对象
            Configuration config = new Configuration(Configuration.VERSION_2_3_28);
            //设置默认加载路径
            File file = new File(loadPath);
            config.setDirectoryForTemplateLoading(file);
            //设置默认编码格式
            config.setDefaultEncoding("utf-8");
            //获取模板
            Template template = config.getTemplate(templateName);
            //时间戳
            long time = System.currentTimeMillis();
            //拼接生成新的图片名称
            String url=time+suffix;
            out = new FileWriter(new File(file,url));
            //生成静态资源
            template.process(data, out);
            //返回地址
            return url;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        return null;
    }
}


模板内容的显示方式:(将里面的内容替换成动态获取:${需要显示的属性})




<div class="wrapper majority article" id="article">
    <div class="info">
        <span><span b>发表时间: </span>${createDate?datetime}</span><span><span b>浏览: </span ><span id="clickCount">${clickCount}                                  </span></span>
    </div>
    <div class="title">${title}</div>
    <div class="content">
        <div>${content}</div>
    </div>
</div>


写写好模板,后台添加内容的时候,页面可以根据id发送请求,获取相对应的内容再渲染到详情页就可以了