FEATURE: New API to create a custom formatter for displaying usernames
This is not exhaustive right now, but a good start and we can add to it over time.
This commit is contained in:
parent
e02ad4249e
commit
a0dd75ba88
|
@ -0,0 +1,4 @@
|
|||
import { registerUnbound } from 'discourse-common/lib/helpers';
|
||||
import { formatUsername } from 'discourse/lib/utilities';
|
||||
|
||||
export default registerUnbound('format-username', formatUsername);
|
|
@ -1,5 +1,6 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { userPath } from 'discourse/lib/url';
|
||||
import { formatUsername } from 'discourse/lib/utilities';
|
||||
|
||||
function replaceSpan($e, username, opts) {
|
||||
let extra = "";
|
||||
|
@ -16,7 +17,7 @@ function replaceSpan($e, username, opts) {
|
|||
extra = `data-name='${username}'`;
|
||||
extraClass = "cannot-see";
|
||||
}
|
||||
$e.replaceWith(`<a href='${userPath(username.toLowerCase())}' class='mention ${extraClass}' ${extra}>@${username}</a>`);
|
||||
$e.replaceWith(`<a href='${userPath(username.toLowerCase())}' class='mention ${extraClass}' ${extra}>@${formatUsername(username)}</a>`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ import { addPostTransformCallback } from 'discourse/widgets/post-stream';
|
|||
import { attachAdditionalPanel } from 'discourse/widgets/header';
|
||||
import { registerIconRenderer, replaceIcon } from 'discourse-common/lib/icon-library';
|
||||
import { addNavItem } from 'discourse/models/nav-item';
|
||||
|
||||
import { replaceFormatter } from 'discourse/lib/utilities';
|
||||
|
||||
// If you add any methods to the API ensure you bump up this number
|
||||
const PLUGIN_API_VERSION = '0.8.11';
|
||||
const PLUGIN_API_VERSION = '0.8.12';
|
||||
|
||||
class PluginApi {
|
||||
constructor(version, container) {
|
||||
|
@ -570,6 +570,25 @@ class PluginApi {
|
|||
addNavItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Registers a function that will format a username when displayed. This will not
|
||||
* be applied when the username is used as an `id` or in URL strings.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* // display usernames in UPPER CASE
|
||||
* api.formatUsername(username => username.toUpperCase());
|
||||
*
|
||||
* ```
|
||||
*
|
||||
**/
|
||||
formatUsername(fn) {
|
||||
replaceFormatter(fn);
|
||||
}
|
||||
}
|
||||
|
||||
let _pluginv01;
|
||||
|
|
|
@ -3,6 +3,7 @@ import { performEmojiUnescape, buildEmojiUrl } from 'pretty-text/emoji';
|
|||
import WhiteLister from 'pretty-text/white-lister';
|
||||
import { sanitize as textSanitize } from 'pretty-text/sanitizer';
|
||||
import loadScript from 'discourse/lib/load-script';
|
||||
import { formatUsername } from 'discourse/lib/utilities';
|
||||
|
||||
function getOpts(opts) {
|
||||
const siteSettings = Discourse.__container__.lookup('site-settings:main'),
|
||||
|
@ -12,7 +13,8 @@ function getOpts(opts) {
|
|||
getURL: Discourse.getURLWithCDN,
|
||||
currentUser: Discourse.__container__.lookup('current-user:main'),
|
||||
censoredWords: site.censored_words,
|
||||
siteSettings
|
||||
siteSettings,
|
||||
formatUsername
|
||||
}, opts);
|
||||
|
||||
return buildOptions(opts);
|
||||
|
|
|
@ -21,6 +21,17 @@ export function escapeExpression(string) {
|
|||
return escape(string);
|
||||
}
|
||||
|
||||
let _usernameFormatDelegate = username => username;
|
||||
|
||||
export function formatUsername(username) {
|
||||
return _usernameFormatDelegate(username || '');
|
||||
}
|
||||
|
||||
export function replaceFormatter(fn) {
|
||||
_usernameFormatDelegate = fn;
|
||||
}
|
||||
|
||||
|
||||
export function avatarUrl(template, size) {
|
||||
if (!template) { return ""; }
|
||||
const rawSize = getRawSize(translateSize(size));
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<div class="names">
|
||||
<span>
|
||||
<h1 class="{{staff}} {{new_user}} {{if nameFirst "full-name" "username"}}">
|
||||
<a href={{user.path}} {{action "showUser"}}>{{if nameFirst user.name username}} {{user-status user currentUser=currentUser}}</a>
|
||||
<a href={{user.path}} {{action "showUser"}}>{{if nameFirst user.name (format-username username)}} {{user-status user currentUser=currentUser}}</a>
|
||||
</h1>
|
||||
|
||||
{{#unless nameFirst}}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
</section>
|
||||
|
||||
<div class="primary-textual">
|
||||
<h1 class="{{if nameFirst "full-name" "username"}}">{{if nameFirst model.name model.username}} {{user-status model currentUser=currentUser}}</h1>
|
||||
<h1 class="{{if nameFirst "full-name" "username"}}">{{if nameFirst model.name (format-username model.username)}} {{user-status model currentUser=currentUser}}</h1>
|
||||
<h2 class="{{if nameFirst "username" "full-name"}}">{{#if nameFirst}}{{model.username}}{{else}}{{model.name}}{{/if}}</h2>
|
||||
{{#if model.title}}
|
||||
<h3>{{model.title}}</h3>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { createWidget } from 'discourse/widgets/widget';
|
|||
import DiscourseURL from 'discourse/lib/url';
|
||||
import { h } from 'virtual-dom';
|
||||
import { emojiUnescape } from 'discourse/lib/text';
|
||||
import { postUrl, escapeExpression } from 'discourse/lib/utilities';
|
||||
import { postUrl, escapeExpression, formatUsername } from 'discourse/lib/utilities';
|
||||
import { setTransientHeader } from 'discourse/lib/ajax';
|
||||
import { userPath } from 'discourse/lib/url';
|
||||
import { iconNode } from 'discourse-common/lib/icon-library';
|
||||
|
@ -79,11 +79,11 @@ createWidget('notification-item', {
|
|||
return I18n.t(scope, { count, group_name });
|
||||
}
|
||||
|
||||
const username = data.display_username;
|
||||
const username = formatUsername(data.display_username);
|
||||
const description = this.description();
|
||||
if (notificationType === LIKED_TYPE && data.count > 1) {
|
||||
const count = data.count - 2;
|
||||
const username2 = data.username2;
|
||||
const username2 = formatUsername(data.username2);
|
||||
if (count===0) {
|
||||
return I18n.t('notifications.liked_2', {description, username, username2});
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { iconNode } from 'discourse-common/lib/icon-library';
|
||||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
import { formatUsername } from 'discourse/lib/utilities';
|
||||
|
||||
function sanitizeName(name){
|
||||
return name.toLowerCase().replace(/[\s_-]/g,'');
|
||||
|
@ -17,10 +18,11 @@ export default createWidget('poster-name', {
|
|||
},
|
||||
|
||||
userLink(attrs, text) {
|
||||
return h('a', { attributes: {
|
||||
href: attrs.usernameUrl,
|
||||
'data-user-card': attrs.username
|
||||
} }, text);
|
||||
return h(
|
||||
'a',
|
||||
{ attributes: { href: attrs.usernameUrl, 'data-user-card': attrs.username } },
|
||||
formatUsername(text)
|
||||
);
|
||||
},
|
||||
|
||||
html(attrs) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { h } from 'virtual-dom';
|
||||
import { formatUsername } from 'discourse/lib/utilities';
|
||||
|
||||
let extraGlyphs;
|
||||
|
||||
|
@ -50,7 +51,7 @@ createWidget('user-menu-links', {
|
|||
model: currentUser,
|
||||
className: 'user-activity-link',
|
||||
icon: 'user',
|
||||
rawLabel: currentUser.username
|
||||
rawLabel: formatUsername(currentUser.username)
|
||||
};
|
||||
|
||||
if (currentUser.is_anonymous) {
|
||||
|
|
|
@ -24,7 +24,8 @@ export function buildOptions(state) {
|
|||
lookupImageUrls,
|
||||
previewing,
|
||||
linkify,
|
||||
censoredWords
|
||||
censoredWords,
|
||||
mentionLookup
|
||||
} = state;
|
||||
|
||||
let features = {
|
||||
|
@ -56,7 +57,7 @@ export function buildOptions(state) {
|
|||
getCurrentUser,
|
||||
currentUser,
|
||||
lookupAvatarByPostNumber,
|
||||
mentionLookup: state.mentionLookup,
|
||||
mentionLookup,
|
||||
emojiUnicodeReplacer,
|
||||
lookupInlineOnebox,
|
||||
lookupImageUrls,
|
||||
|
|
Loading…
Reference in New Issue