Public account: MarkerHub (pay attention to get more project resources)

Eblog codebase: github.com/markerhub/e…

Eblog project video: www.bilibili.com/video/BV1ri…


Development Document Catalog:

(Eblog) 1. Set up the project architecture and initialized the home page

(EBLOG) 2. Integrate Redis and project elegant exception handling and return result encapsulation

(eblog) 3, using Redis zset ordered set to achieve a hot feature of the week

(EBLOG) 4, customize Freemaker label to achieve blog homepage data filling

(Eblog) 5, blog classification filling, login registration logic

(EBLOG) 6. Set up blog publishing collection and user center

(eblog) 7, message asynchronous notification, details adjustment

8. Blog search engine development and background selection

(Eblog) 9. Instant group chat development, chat history, etc


Front and back end separation project vueblog please click here: super detailed! 4 hours to develop a SpringBoot+ Vue front and back separated blog project!!


Custom Freemarker tag

The first thing to do is get the data at the top. To give you a better idea of Freemarker, we define a Freemarker tag and use the tag to display our data.

To customize the freemarker tag you need to implement this interface and override the Excute method:

public interface TemplateDirectiveModel extends TemplateModel {
  public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException;
}

Copy the code

The above parameters are as follows:

  • Env: System environment variable, usually used to output related content, such as Writer out = env.getOut().

  • Params: The object passed by the custom tag, whose key = the parameter name of the custom tag, and whose value is of type TemplateModel, which is an interface type, We usually use TemplateScalarModel interface to replace it takes a String value, such as TemplateScalarModel. GetAsString (); There are other commonly used alternatives, such as TemplateNumberModel to get number, TemplateHashModel, and so on.

  • The loopVars loop replaces variables.

  • Body is used to process content in custom tags, such as <@myDirective>, which will be processed. When the tag is in the <@myDirective /> format, body=null.

In order to use this interface better, we need to encapsulate another layer. Here I refer to the ENCAPSULATION of this interface by the Mblog project.

com.example.common.template

  • DirectiveHandler

  • TemplateDirective

  • TemplateModelUtils

I copied the above three classes from the MBlog project and changed the package path

Mblog original path:

Gitee.com/mtons/mblog…

With that wrapped, we need to define a tag template that inherits TemplateDirective, overwrite getName () and excute (DirectiveHandler handler); You can see that there is a handler in the excute method. This handler should be easy to use.

Let’s define a blog list tag com. Example. Templates. PostsTemplate

@Component
public class PostsTemplate extends TemplateDirective {
    @Autowired
    PostService postService;
    @Override
    public String getName() {
        return "posts";
    }
    @Override
    public void execute(DirectiveHandler handler) throws Exception {
        Long categoryId = handler.getLong("categoryId", 0);
        int pn = handler.getInteger("pn", 1);
        int size = handler.getInteger("size", 10);
        String order = handler.getString("order"."created"); Page page = new Page(pn, size); IPage results = postService.paging(page, categoryId, order); handler.put(RESULTS, results).render(); }}Copy the code

As you can see from the above code, our tag takes several parameters: categoryId, PN, size, and order. The wrapper is then wrapped into two classes: Page and QueryWrapper, both of which are wrapped in Mybatis – Plus for paging and parameter queries.

For caching purposes, instead of passing QueryWrapper directly, we pass parameters directly so that we can use the parameters as cache keys.

Postservice.paging (Page Page, Long categoryId, String Order); Methods.

@Override
@Cacheable(cacheNames = "cache_post", key = "'page_' + #page.current + '_' + #page.size " +
        "+ '_query_' +#categoryId + '_' + #order") public IPage paging(Page page, Long categoryId, String order) { QueryWrapper wrapper = new QueryWrapper<Post>() .eq(categoryId ! = 0,"category_id", categoryId)
            .orderByDesc(order);
    IPage<PostVo> pageData = postMapper.selectPosts(page, wrapper);
    return pageData;
}

Copy the code

This interface in turn calls the mapper interface and uses the @cacheable annotation to indicate the cache result. Key is the pn of the page, size, categoryId, and order parameters. Ok, so above I’ve defined a template tag that needs to be used in the page and I need to configure this tag into freemarker, so let’s define a FreemarkerConfig.

  • com.example.config.FreemarkerConfig
@Configuration
public class FreemarkerConfig {
    @Autowired
    private freemarker.template.Configuration configuration;
    @Autowired
    private ApplicationContext applicationContext;
    @PostConstruct
    public void setUp() {
        configuration.setSharedVariable("posts", applicationContext.getBean(PostsTemplate.class)); }}Copy the code

Page use tags

Ok, so the freemarker tag is generated and we’ll use it on the page. The tag name we defined is posts, and the result is results. So for the top module, we write:

  • templates/index.ftl

The results are as follows:

Home Sidebar – This Week’s Talk (continued)

In the last assignment, we completed the data interface that has been talked about this week:

But we haven’t shown our data in the page yet, the logic would be to write ajax in the page and call the interface to display the data. Now that we’ve learned to customize freemarker, I think it’s easier to define a tag, so let’s change the interface to a template tag.

Ok, let’s install the process just now and comb it out:

  • First define a template, HotsTemplate, that inherits the TemplateDirective

  • Override the getName and execute methods

  • Then configure the injection tag in FreemarkerConfig

  • Use tags in pages

*/ @Component public class HotsTemplate extends TemplateDirective {@autoWired RedisUtil RedisUtil; @Override public StringgetName() {
        return "hots"; } @Override public void execute(DirectiveHandler handler) throws Exception { Set<ZSetOperations.TypedTuple> lastWeekRank  = redisUtil.getZSetRank("last_week_rank", 0, 6);
        List<Map<String, Object>> hotPosts = new ArrayList<>();
        for (ZSetOperations.TypedTuple typedTuple : lastWeekRank) {
            Map<String, Object> map = new HashMap<>();
            map.put("comment_count", typedTuple.getScore());
            map.put("id", redisUtil.hget("rank_post_" + typedTuple.getValue(), "post:id"));
            map.put("title", redisUtil.hget("rank_post_" + typedTuple.getValue(), "post:title")); hotPosts.add(map); } handler.put(RESULTS, hotPosts).render(); }}Copy the code

Execute is a move from this week’s hot interface. And then the freemarkerConfig. SetUp

configuration
.
setSharedVariable
(
"hots"
,
 applicationContext
.
getBean
(
HotsTemplate
.
class
));
Copy the code

With this line of code, you can use it on your page.

  • templates/inc/right.ftl
<dl class="fly-panel fly-list-one">
    <dt class="fly-panel-title"</dt> <@hots> <#list results as post>
            <dd>
                <a href="jie/detail.html">${post.title}</a>
                <span><i class="iconfont icon-pinglun1"></i> ${post.comment_count}</span>
            </dd>
        </#list>
    </@hots>
</dl>

Copy the code

All right, that’s the homework for this time. We need to learn to quickly customize the Freemarker tag. The Freemarker template engine is also the dominant page engine.

(after)

MarkerHub Article Index:

Github.com/MarkerHub/J…