Various Plugin Enhancements and Extension Points

This commit is contained in:
Robin Ward
2016-03-11 15:52:18 -05:00
parent 841cec1bc1
commit 1006b1ba94
10 changed files with 82 additions and 19 deletions

View File

@ -110,7 +110,7 @@ function buildConnectorCache() {
_connectorCache[outletName].removeObject(viewClass); _connectorCache[outletName].removeObject(viewClass);
} else { } else {
if (!/\.raw$/.test(uniqueName)) { if (!/\.raw$/.test(uniqueName)) {
viewClass = Em.View.extend({ classNames: [outletName + '-outlet', uniqueName] }); viewClass = Ember.View.extend({ classNames: [outletName + '-outlet', uniqueName] });
} }
} }
@ -172,8 +172,11 @@ Ember.HTMLBars._registerHelper('plugin-outlet', function(params, hash, options,
// just shove it in. // just shove it in.
const viewClass = (childViews.length > 1) ? Ember.ContainerView : childViews[0]; const viewClass = (childViews.length > 1) ? Ember.ContainerView : childViews[0];
const newHash = viewInjections(env.data.view.container);
if (hash.tagName) { newHash.tagName = hash.tagName; }
delete options.fn; // we don't need the default template since we have a connector delete options.fn; // we don't need the default template since we have a connector
env.helpers.view.helperFunction.call(this, [viewClass], viewInjections(env.data.view.container), options, env); env.helpers.view.helperFunction.call(this, [viewClass], newHash, options, env);
const cvs = env.data.view._childViews; const cvs = env.data.view._childViews;
if (childViews.length > 1 && cvs && cvs.length) { if (childViews.length > 1 && cvs && cvs.length) {

View File

@ -5,7 +5,7 @@ import { addButton } from 'discourse/widgets/post-menu';
import { includeAttributes } from 'discourse/lib/transform-post'; import { includeAttributes } from 'discourse/lib/transform-post';
import { addToolbarCallback } from 'discourse/components/d-editor'; import { addToolbarCallback } from 'discourse/components/d-editor';
import { addWidgetCleanCallback } from 'discourse/components/mount-widget'; import { addWidgetCleanCallback } from 'discourse/components/mount-widget';
import { decorateWidget, changeSetting } from 'discourse/widgets/widget'; import { createWidget, decorateWidget, changeSetting } from 'discourse/widgets/widget';
import { onPageChange } from 'discourse/lib/page-tracker'; import { onPageChange } from 'discourse/lib/page-tracker';
import { preventCloak } from 'discourse/widgets/post-stream'; import { preventCloak } from 'discourse/widgets/post-stream';
@ -89,6 +89,8 @@ class PluginApi {
const src = Discourse.Emoji.urlFor(emoji); const src = Discourse.Emoji.urlFor(emoji);
return dec.h('img', { className: 'emoji', attributes: { src } }); return dec.h('img', { className: 'emoji', attributes: { src } });
}); });
iconBody = result.emoji.split('|').map(name => dec.attach('emoji', { name }));
} }
if (result.text) { if (result.text) {
@ -268,11 +270,20 @@ class PluginApi {
preventCloak(postId) { preventCloak(postId) {
preventCloak(postId); preventCloak(postId);
} }
/**
* Exposes the widget creating ability to plugins. Plugins can
* register their own plugins and attach them with decorators.
* See `createWidget` in `discourse/widgets/widget` for more info.
**/
createWidget(name, args) {
return createWidget(name, args);
}
} }
let _pluginv01; let _pluginv01;
function getPluginApi(version) { function getPluginApi(version) {
if (version === "0.1") { if (version === "0.1" || version === "0.2") {
if (!_pluginv01) { if (!_pluginv01) {
_pluginv01 = new PluginApi(version, Discourse.__container__); _pluginv01 = new PluginApi(version, Discourse.__container__);
} }

View File

@ -46,11 +46,14 @@
{{#if currentUser.staff}} {{#if currentUser.staff}}
<li><a href={{model.adminPath}} class="btn">{{fa-icon "wrench"}}{{i18n 'admin.user.show_admin_profile'}}</a></li> <li><a href={{model.adminPath}} class="btn">{{fa-icon "wrench"}}{{i18n 'admin.user.show_admin_profile'}}</a></li>
{{/if}} {{/if}}
{{plugin-outlet "user-profile-controls" tagName="li"}}
{{#if collapsedInfo}} {{#if collapsedInfo}}
{{#if viewingSelf}} {{#if viewingSelf}}
<li><a {{action "expandProfile"}} href class="btn">{{fa-icon "angle-double-down"}}{{i18n 'user.expand_profile'}}</a></li> <li><a {{action "expandProfile"}} href class="btn">{{fa-icon "angle-double-down"}}{{i18n 'user.expand_profile'}}</a></li>
{{/if}} {{/if}}
{{/if}} {{/if}}
</ul> </ul>
</section> </section>

View File

@ -22,6 +22,20 @@ class DecoratorHelper {
**/ **/
// h() is attached via `prototype` below // h() is attached via `prototype` below
/**
* Attach another widget inside this one.
*
* ```
* return helper.attach('widget-name');
* ```
*/
attach(name, attrs, state) {
attrs = attrs || this.widget.attrs;
state = state || this.widget.state;
return this.widget.attach(name, attrs, state);
}
/** /**
* Returns the model associated with this widget. When decorating * Returns the model associated with this widget. When decorating
* posts this will normally be the post. * posts this will normally be the post.

View File

@ -0,0 +1,9 @@
import { createWidget } from 'discourse/widgets/widget';
export default createWidget('emoji', {
tagName: 'img.emoji',
buildAttributes(attrs) {
return { src: Discourse.Emoji.urlFor(attrs.name) };
},
});

View File

@ -148,6 +148,33 @@ class User < ActiveRecord::Base
User.where(username_lower: lower).blank? && !SiteSetting.reserved_usernames.split("|").include?(username) User.where(username_lower: lower).blank? && !SiteSetting.reserved_usernames.split("|").include?(username)
end end
def self.plugin_staff_user_custom_fields
@plugin_staff_user_custom_fields ||= {}
end
def self.register_plugin_staff_custom_field(custom_field_name, plugin)
plugin_staff_user_custom_fields[custom_field_name] = plugin
end
def self.whitelisted_user_custom_fields(guardian)
fields = []
if SiteSetting.public_user_custom_fields.present?
fields += SiteSetting.public_user_custom_fields.split('|')
end
if guardian.is_staff?
if SiteSetting.staff_user_custom_fields.present?
fields += SiteSetting.staff_user_custom_fields.split('|')
end
plugin_staff_user_custom_fields.each do |k, v|
fields << k if v.enabled?
end
end
fields.uniq
end
def effective_locale def effective_locale
if SiteSetting.allow_user_locale && self.locale.present? if SiteSetting.allow_user_locale && self.locale.present?
self.locale self.locale

View File

@ -318,15 +318,10 @@ class UserSerializer < BasicUserSerializer
end end
def custom_fields def custom_fields
fields = nil fields = User.whitelisted_user_custom_fields(scope)
if scope.can_edit?(object) if scope.can_edit?(object)
fields = DiscoursePluginRegistry.serialized_current_user_fields.to_a fields += DiscoursePluginRegistry.serialized_current_user_fields.to_a
end
if SiteSetting.public_user_custom_fields.present?
fields ||= []
fields += SiteSetting.public_user_custom_fields.split('|')
end end
if fields.present? if fields.present?

View File

@ -67,6 +67,10 @@ class Plugin::Instance
klass.send(:define_method, "include_#{attr}?") { plugin.enabled? } klass.send(:define_method, "include_#{attr}?") { plugin.enabled? }
end end
def whitelist_staff_user_custom_field(field)
User.register_plugin_staff_custom_field(field, self)
end
# Extend a class but check that the plugin is enabled # Extend a class but check that the plugin is enabled
# for class methods use `add_class_method` # for class methods use `add_class_method`
def add_to_class(klass, attr, &block) def add_to_class(klass, attr, &block)

View File

@ -54,13 +54,11 @@ class TopicView
filter_posts(options) filter_posts(options)
if SiteSetting.public_user_custom_fields.present? && @posts if @posts
@user_custom_fields = User.custom_fields_for_ids(@posts.map(&:user_id), SiteSetting.public_user_custom_fields.split('|')) added_fields = User.whitelisted_user_custom_fields(@guardian)
end if added_fields.present?
@user_custom_fields = User.custom_fields_for_ids(@posts.map(&:user_id), added_fields)
if @guardian.is_staff? && SiteSetting.staff_user_custom_fields.present? && @posts end
@user_custom_fields ||= {}
@user_custom_fields.deep_merge!(User.custom_fields_for_ids(@posts.map(&:user_id), SiteSetting.staff_user_custom_fields.split('|')))
end end
whitelisted_fields = TopicView.whitelisted_post_custom_fields(@user) whitelisted_fields = TopicView.whitelisted_post_custom_fields(@user)

View File

@ -38,7 +38,6 @@ describe User do
Jobs.expects(:enqueue).with(:send_system_message, user_id: user.id, message_type: 'welcome_user').never Jobs.expects(:enqueue).with(:send_system_message, user_id: user.id, message_type: 'welcome_user').never
user.enqueue_welcome_message('welcome_user') user.enqueue_welcome_message('welcome_user')
end end
end end
describe '.approve' do describe '.approve' do