# 自定义帖子小部件使用的模板

**URL:** https://meta.discourse.org/t/customize-template-used-by-post-widget/97168
**Category:** Development
**Created:** [2018年九月14日 05:53 UTC](https://meta.discourse.org/t/customize-template-used-by-post-widget/97168 "2018-09-14T05:53:57Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![will\_io](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/will_io/32/147541_2.png) [@will\_io](https://meta.discourse.org/u/will_io)
#### Post date: [2018年九月14日 05:53 UTC](https://meta.discourse.org/t/customize-template-used-by-post-widget/97168/1 "2018-09-14T05:53:57Z")

</div>

On the pre-v2 installs I used to override the post hbs templates. I noticed in the github notes that the Discourse team converted this into a widget to enhance performance and it’s very noticeable in the browser. Within the widget layout the following looks interesting to me:

`app/assets/javascripts/discourse/widgets/post-placeholder.js.es6`

* * *

```javascript
import { createWidget } from "discourse/widgets/widget";
import hbs from "discourse/widgets/hbs-compiler";

export default createWidget("post-placeholder", {
  tagName: "article.placeholder",
  template: hbs`
    <div class='row'>
      <div class='topic-avatar'>
        <div class='placeholder-avatar'></div>
      </div>
      <div class='topic-body'>
        <div class='placeholder-text'></div>
        <div class='placeholder-text'></div>
        <div class='placeholder-text'></div>
      </div>
    </div>
  `
});

```

* * *

`app/assets/javascripts/discourse/widgets/post.js.es6`

```javascript

 createWidget("post-article", {
  tagName: "article.boxed.onscreen-post",
  buildKey: attrs => `post-article-${attrs.id}`,

  defaultState() {
    return { repliesAbove: [] };
  },

  buildId(attrs) {
    return `post_${attrs.post_number}`;
  },

  buildClasses(attrs) {
    let classNames = [];
    if (attrs.via_email) {
      classNames.push("via-email");
    }
    if (attrs.isAutoGenerated) {
      classNames.push("is-auto-generated");
    }
    return classNames;
  },

  buildAttributes(attrs) {
    return { "data-post-id": attrs.id, "data-user-id": attrs.user_id };
  },

  html(attrs, state) {
    const rows = [h("a.tabLoc", { attributes: { href: "" } })];
    if (state.repliesAbove.length) {
      const replies = state.repliesAbove.map(p => {
        return this.attach("embedded-post", p, {
          model: this.store.createRecord("post", p),
          state: { above: true }
        });
      });

      rows.push(
        h(
          "div.row",
          h("section.embedded-posts.top.topic-body.offset2", [
            this.attach("button", {
              title: "post.collapse",
              icon: "chevron-down",
              action: "toggleReplyAbove",
              actionParam: "true",
              className: "btn collapse-down"
            }),
            replies
          ])
        )
      );
    }

    rows.push(
      h("div.row", [
        this.attach("post-avatar", attrs),
        this.attach("post-body", attrs)
      ])
    );
    return rows;
  },

  _getTopicUrl() {
    const post = this.findAncestorModel();
    return post ? post.get("topic.url") : null;
  },

  toggleReplyAbove(goToPost = "false") {
    const replyPostNumber = this.attrs.reply_to_post_number;

    // jump directly on mobile
    if (this.attrs.mobileView) {
      const topicUrl = this._getTopicUrl();
      if (topicUrl) {
        DiscourseURL.routeTo(`${topicUrl}/${replyPostNumber}`);
      }
      return Ember.RSVP.Promise.resolve();
    }

    if (this.state.repliesAbove.length) {
      this.state.repliesAbove = [];
      if (goToPost === "true") {
        DiscourseURL.routeTo(
          `${this.attrs.topicUrl}/${this.attrs.post_number}`
        );
      }
      return Ember.RSVP.Promise.resolve();
    } else {
      const topicUrl = this._getTopicUrl();
      return this.store
        .find("post-reply-history", { postId: this.attrs.id })
        .then(posts => {
          this.state.repliesAbove = posts.map(p => {
            p.shareUrl = `${topicUrl}/${p.post_number}`;
            return transformBasicPost(p);
          });
        });
    }
  }
});

```

But I am not sure how or where to customize the post `.row` and dont want to go the hackish route if I don’t have to. Do I want to reopen the widget and Customize it through the Header tab in the admin interface or would it be better to use a plugin to override the files? Any nudges in the right direction would be much appreciated I basically want to make slight rearrangements/additions to the post layout.

Thank you and sorry if this is a duplicate topic.

_Edited_: because mobile device butchered my spelling

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [2018年九月14日 10:58 UTC](https://meta.discourse.org/t/customize-template-used-by-post-widget/97168/2 "2018-09-14T10:58:42Z")

</div>

The best way to modify the post templates is to use the `decorateWidget` method in the plugin API. You can use that to add content before/after the built-in template. There are some brief instructions [here](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648#heading--4-c-6) for doing that in a theme.

To fully override the template you would use `reopenWidget` to override the `html()` method. Some instructions are [here](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648/1#heading--4-c-5).

Adding things before/after is a far more ‘future proof’ way to work, so try and do that if you can. If you have some specifics on what you want to change about the post layout, I’m sure someone will be able to give some more specific advice.
