[20211202] CmsWing code analysis - src/controller/home/detail.js

2021SC@SDUSC

Starting from this article, we will analyze with the corresponding html file to infer more details of use by calling the JavaScript file.

view/home/ceshi_hooks.html

Here is the hook. What is a hook? https://www.jianshu.com/p/3382cc765b39 This paper introduces the use of hook function. Hook technology is also called hook function. Before the system calls the function, the hook program captures the message first, and the hook function obtains the control right first. At this time, the hook function can not only process (change) the execution behavior of the function, but also force the end of message delivery. In short, it is to pull out the program of the system and turn it into a code fragment for our own execution. Of course, this article is about hook technology in Java programs, but it can also be seen in JavaScript.

In this Html document, let's see how the test hook works.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--belt $hook_type Parameter, HOOK+@Hook name+@$hook_type-->
{{HOOK@adminArticleEdit@1|safe}} <hr>
<!--belt $hook_key Parameter view hook call, HOOKS+@Hook name[$hook_key]-->
{{HOOKS@adminArticleEdit['aaaa']|safe}}<hr>
{{HOOKS@adminArticleEdit['bbbb']|safe}}<hr>
<!--belt $hook_type and $hook.key Parameter view hook call, HOOKS+@Hook name[$hook_type]+@$hook_type-->
{{HOOKS@adminArticleEdit@2['bbbb']|safe}}<br>
<!--Default call HOOK+@Hook name-->
{{HOOK@adminArticleEdit|safe}}

</body>
</html>

The previous is the usual writing mode of Html documents. Needless to say. Let's focus on the body. Here is a hook call with some examples written, including $hook_ View hook call of type parameter with $hook_type and $hook.key parameter view hook call with $hook_ The type and $hook.key parameters are called by the view hook, which is called by default.

src/controller/home/detail.js

Let's go back to src/controller/home/detail.js. Here are some hook related functions.

this.assign('info', info);
// Bottom hook of document content
await this.hook('documentDetailAfter', info);
// Video player hook
await this.hook('videoPlayer', info);
// Load page header bottom hook
const editor = !think.isEmpty(info.editor) ? info.editor : await this.model('cmswing/model').get_model(info.model_id, 'editor');
const field_group = await this.model('cmswing/model').get_model(info.model_id, 'field_group');
const fields = await this.model('cmswing/attribute').get_model_attribute(info.model_id, true);
const fg = parse_config_attr(field_group);
const farr = [];
for (const key in fg) {
  for (const f of fields[key]) {
    if (f.type === 'editor') {
      farr.push(f);
      // Add editor hook
      if (editor === '0') {
        await this.hook('pageHeader', f.name, f.value, {$hook_key: f.name});
        await this.hook('pageFooter', f.name, f.value, {$hook_key: f.name});
        await this.hook('pageContent', f.name, info[f.name], {$hook_key: f.name});
      } else {
        await this.hook('pageHeader', f.name, f.value, {$hook_key: f.name, $hook_type: editor});
        await this.hook('pageFooter', f.name, f.value, {$hook_key: f.name, $hook_type: editor});
        await this.hook('pageContent', f.name, info[f.name], {$hook_key: f.name, $hook_type: editor});
      }
    };
  };
};

The bottom hooks of document content, video player and loading page header are all hooks.

Next is the familiar browser difference:

    // Judge browsing client
    if (this.isMobile) {
      // Mobile phone template
      if (!think.isEmpty(info.template) && info.template != 0) {
        temp = info.template; // todo set detail template
      } else if (!think.isEmpty(cate.template_m_detail)) {
        temp = cate.template_m_detail; // Classification template has been set
      } else {
        temp = model;
      }
      // console.log(temp);
      // Content paging
      // if (!think.isEmpty(info.content)) {
      //   info.content = info.content.split('_ueditor_page_break_tag_');
      // }
      return this.display(this.mtpl(temp));
    } else {
      if (!think.isEmpty(info.template) && info.template != 0) {
        temp = info.template; // Detail template set
      } else if (!think.isEmpty(cate.template_detail)) {
        temp = cate.template_detail; // Classification template has been set
      } else {
        temp = model;
      }
      // console.log(temp);
      // console.log(info);
      // Content paging
      // if (!think.isEmpty(info.content)) {
      //   info.content = info.content.split('_ueditor_page_break_tag_');
      // }
      return this.display(`home/detail_${temp}`);
    }
  }

Finally, there is a piece of code about downloading, which is very long but not very complex.

  /**
     * download
     */
  async downloadgetidAction() {
    const id = decodeURIComponent(this.get('id')).split('||');
    const db = this.model('document_download');
    const info = await db.find(id[0]);
    // console.log(info);
    const file_id = info.file_id;
    // console.log(file_id);
    let dlink;
    if (Number(id[1]) === 1) {
      // console.log(location);
      const d = await get_file(file_id);
      if (Number(d.type) === 2) {
        // Seven cattle Download
        // dlink = await get_file(file_id,"savename",true);
        const qiniu = this.extService('qiniu', 'attachment');
        dlink = await qiniu.download(d.savename);
      } else {
        // Local download
        dlink = `/home/detail/download?id=${d.id}#${d.name}`;
      }
      // console.log(dlink);
      // Access statistics
      await db.where({id: info.id}).increment('download');
      // return this.redirect(dlink);
      this.assign('durl', dlink);
      if (this.isMobile) {
        // Mobile phone template
        return this.display(`home/mobile/detail_downloadgetid`);
      } else {
        return this.display();
      }
    } else if (id[1] == 2) {
      dlink = id[2];
      await db.where({id: info.id}).increment('download');
      return this.redirect(dlink);
    } else if (id[1] == 3) {
      // Return network disk extraction code
      const pan = info.panurl.split('\r\n');
      for (const v of pan) {
        const varr = v.split('|');
        console.log(varr[1]);
        if (!think.isEmpty(varr[2]) && think._.trim(id[2]) == think._.trim(varr[1])) {
          this.assign({
            title: varr[0],
            durl: varr[1],
            sn: varr[2]
          });
        }
      }
      await db.where({id: info.id}).increment('download');
      if (this.isMobile) {
        // Mobile phone template
        return this.display(`home/mobile/detail_downloadgetid`);
      } else {
        return this.display();
      }
    }
  }

It includes some judgment and diversion work, which will not be repeated. Finally, there is still the code related to download——

  // Download File
  async downloadAction() {
    const file = await get_file(this.get('id'));
    const filePath = `${think.ROOT_PATH}/www${file.savename}`;
    const userAgent = this.userAgent.toLowerCase();
    let hfilename = '';
    if (userAgent.indexOf('msie') >= 0 || userAgent.indexOf('chrome') >= 0) {
      hfilename = `=${encodeURIComponent(file.name)}`;
    } else if (userAgent.indexOf('firefox') >= 0) {
      hfilename = `*="utf8''${encodeURIComponent(file.name)}"`;
    } else {
      hfilename = `=${Buffer.from(file.name).toString('binary')}`;
    }
    this.ctx.set('Content-Disposition', `attachment; filename${hfilename}`);
    return this.download(filePath);
  }
};

summary

src/controller/home/detail.js shows us the various functions required for the details of the home page. In terms of function, it may not be complex, but it should be comprehensive. From this, we can also see how much distance it takes from a framework to the real display of a page.

Tags: Javascript

Posted on Thu, 02 Dec 2021 14:48:40 -0500 by fotobleu