FEATURE: Use Glimmer compiler for widget templates
Widgets can now specify a template which is precompiled using Glimmer's
AST and then converted into our virtual dom code.
Example:
```javascript
createWidget('post-link-arrow', {
template: hbs`
{{#if attrs.above}}
<a class="post-info arrow" title={{i18n "topic.jump_reply_up"}}>
{{fa-icon "arrow-up"}}
</a>
{{else}}
<a class="post-info arrow" title={{i18n "topic.jump_reply_down"}}>
{{fa-icon "arrow-down"}}
</a>
{{/if}}
`,
click() {
DiscourseURL.routeTo(this.attrs.shareUrl);
}
});
```
This commit is contained in:
@@ -2,21 +2,21 @@ import PostCooked from 'discourse/widgets/post-cooked';
|
||||
import DecoratorHelper from 'discourse/widgets/decorator-helper';
|
||||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
import { iconNode } from 'discourse-common/lib/icon-library';
|
||||
import DiscourseURL from 'discourse/lib/url';
|
||||
import hbs from 'discourse/widgets/hbs-compiler';
|
||||
|
||||
createWidget('post-link-arrow', {
|
||||
html(attrs) {
|
||||
if (attrs.above) {
|
||||
return h('a.post-info.arrow', {
|
||||
attributes: { title: I18n.t('topic.jump_reply_up') }
|
||||
}, iconNode('arrow-up'));
|
||||
} else {
|
||||
return h('a.post-info.arrow', {
|
||||
attributes: { title: I18n.t('topic.jump_reply_down') }
|
||||
}, iconNode('arrow-down'));
|
||||
}
|
||||
},
|
||||
template: hbs`
|
||||
{{#if attrs.above}}
|
||||
<a class="post-info arrow" title={{i18n "topic.jump_reply_up"}}>
|
||||
{{fa-icon "arrow-up"}}
|
||||
</a>
|
||||
{{else}}
|
||||
<a class="post-info arrow" title={{i18n "topic.jump_reply_down"}}>
|
||||
{{fa-icon "arrow-down"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
`,
|
||||
|
||||
click() {
|
||||
DiscourseURL.routeTo(this.attrs.shareUrl);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function hbs() {
|
||||
console.log('Templates should be precompiled server side');
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import hbs from 'discourse/widgets/hbs-compiler';
|
||||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
|
||||
@@ -23,14 +24,17 @@ createWidget('menu-links', {
|
||||
|
||||
createWidget('menu-panel', {
|
||||
tagName: 'div.menu-panel',
|
||||
template: hbs`
|
||||
<div class='panel-body'>
|
||||
<div class='panel-body-contents clearfix'>
|
||||
{{yield}}
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
buildAttributes(attrs) {
|
||||
if (attrs.maxWidth) {
|
||||
return { 'data-max-width': attrs.maxWidth };
|
||||
}
|
||||
},
|
||||
|
||||
html(attrs) {
|
||||
return h('div.panel-body', h('div.panel-body-contents.clearfix', attrs.contents()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
import hbs from 'discourse/widgets/hbs-compiler';
|
||||
|
||||
export default createWidget('post-placeholder', {
|
||||
tagName: 'article.placeholder',
|
||||
|
||||
html() {
|
||||
return h('div.row', [
|
||||
h('div.topic-avatar', h('div.placeholder-avatar')),
|
||||
h('div.topic-body', [
|
||||
h('div.placeholder-text'),
|
||||
h('div.placeholder-text'),
|
||||
h('div.placeholder-text')
|
||||
])
|
||||
]);
|
||||
}
|
||||
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>
|
||||
`
|
||||
});
|
||||
|
||||
@@ -2,13 +2,11 @@ import { iconNode } from 'discourse-common/lib/icon-library';
|
||||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
import { avatarFor } from 'discourse/widgets/post';
|
||||
import hbs from 'discourse/widgets/hbs-compiler';
|
||||
|
||||
createWidget('pm-remove-group-link', {
|
||||
tagName: 'a.remove-invited',
|
||||
|
||||
html() {
|
||||
return iconNode('times');
|
||||
},
|
||||
template: hbs`{{fa-icon "times"}}`,
|
||||
|
||||
click() {
|
||||
bootbox.confirm(I18n.t("private_message_info.remove_allowed_group", {name: this.attrs.name}), (confirmed) => {
|
||||
@@ -35,10 +33,7 @@ createWidget('pm-map-user-group', {
|
||||
|
||||
createWidget('pm-remove-link', {
|
||||
tagName: 'a.remove-invited',
|
||||
|
||||
html() {
|
||||
return iconNode('times');
|
||||
},
|
||||
template: hbs`{{fa-icon "times"}}`,
|
||||
|
||||
click() {
|
||||
bootbox.confirm(I18n.t("private_message_info.remove_allowed_user", {name: this.attrs.username}), (confirmed) => {
|
||||
|
||||
@@ -112,6 +112,10 @@ export function createWidget(name, opts) {
|
||||
opts.html = opts.html || emptyContent;
|
||||
opts.draw = drawWidget;
|
||||
|
||||
if (opts.template) {
|
||||
opts.html = opts.template;
|
||||
}
|
||||
|
||||
Object.keys(opts).forEach(k => result.prototype[k] = opts[k]);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user