我正在参考以下主题:
我的目标是找到一种方法,为特定群组的成员显示一个次要的新建主题按钮。该群组拥有论坛中某个私密区域的访问权限,我希望无论他们当前位于哪个页面,点击该按钮都能在该私密区域创建新主题。此外,我还希望为该按钮配合使用主题模板或类似的模板功能。我认为我已经找到了如何根据 body 元素上的主要群组类来选择性添加按钮,但目前我还不太熟悉如何将模板文本(或主题模板)插入到通过该次要按钮创建的新主题中。有人能提供一些指导吗?
我正在参考以下主题:
我的目标是找到一种方法,为特定群组的成员显示一个次要的新建主题按钮。该群组拥有论坛中某个私密区域的访问权限,我希望无论他们当前位于哪个页面,点击该按钮都能在该私密区域创建新主题。此外,我还希望为该按钮配合使用主题模板或类似的模板功能。我认为我已经找到了如何根据 body 元素上的主要群组类来选择性添加按钮,但目前我还不太熟悉如何将模板文本(或主题模板)插入到通过该次要按钮创建的新主题中。有人能提供一些指导吗?
这是可行的。您需要先使用主题模板准备您的分类。前往您想要使用的分类,并按如下方式编辑其主题模板:
然后,找出该分类的 ID。您可以通过访问 your.site.com/categories.json 来实现这一点。
在 Meta 上,它看起来像这样:
可能有更好的方法可以找到 categoryId,但这里使用的方法是有效的。
现在,假设我想使用 bug 分类。根据 /categories.json,它的 ID 为 “1”。
对于 #feature,它的 ID 为 “2”,依此类推。
现在您已经拥有了 ID,并且该分类已设置了主题模板,您可以从主题中复制代码,进行一些修改,然后将其添加到一个单独的主题组件中。
我已经在这里完成了修改,因此您只需复制以下内容并根据需要更改值即可:
<script type="text/discourse-plugin" version="0.8.18">
api.decorateWidget("header-buttons:after", helper => {
if (api.getCurrentUser()) {
// 根据您的需求编辑以下两项
var $ntb_text = "按钮文本",
$ntb_icon = "plus",
// 无需编辑以下项
$ntb_icon_class = ".fa-" + $ntb_icon,
$ntb_button_class = "btn btn-default btn btn-icon-text",
$ntb_button_helper = "button#new-create-topic-custom",
$ntb_icon_helper =
"i.fa" + $ntb_icon_class + ".d-icon .d-icon-" + $ntb_icon,
$ntb_label_helper = "span.d-button-label";
const createTopicCustom = function() {
const container = Discourse.__container__;
const Composer = require("discourse/models/composer").default;
const controller = container.lookup("controller:navigation/category");
const composerController = container.lookup("controller:composer");
composerController.open({
action: Composer.CREATE_TOPIC,
draftKey: Composer.DRAFT,
// 在下方设置分类 ID
// 参考 site.com/categories.json
categoryId: 3
});
};
return helper.h(
$ntb_button_helper,
{
className: $ntb_button_class,
title: $ntb_text,
onclick: createTopicCustom
},
[helper.h($ntb_icon_helper), helper.h($ntb_label_helper, $ntb_text)]
);
}
});
</script>
将此代码放入“通用”部分的 <head> 中。
完成后,您应该会得到类似以下的效果:(我通过 CSS 添加了边距)
点击新按钮将打开撰写器,其中包含您选择的分类,并且该分类的主题模板也会显示出来。
根据以下内容,我假设这就是您所需要的:
Thanks Joe. I’ve already found a use for your instructions above. Very helpful.
Do you know how to create a PM, rather than posting into a category?
eg: Is there a CategoryID specifically for PM messages?
For a PM you’d need to set a few of the composer options differently.
Something like this:
(Same as above, in a theme component in the </head> section)
<script type="text/discourse-plugin" version="0.8.18">
api.decorateWidget("header-buttons:after", helper => {
if (Discourse.User.current()) {
// edit these two to your liking
var $ntb_text = "New Personal Message",
$ntb_icon = "heart",
// no need to edit these
$ntb_icon_class = ".fa-" + $ntb_icon,
$ntb_button_class = "btn btn-default btn btn-icon-text",
$ntb_button_helper = "button#new-create-topic-custom",
$ntb_icon_helper =
"i.fa" + $ntb_icon_class + ".d-icon .d-icon-" + $ntb_icon,
$ntb_label_helper = "span.d-button-label";
const createPM = function() {
const container = Discourse.__container__,
Composer = require("discourse/models/composer").default,
composerController = container.lookup("controller:composer");
composerController.open({
action: Composer.PRIVATE_MESSAGE,
// 1- set recipients (Case Sensitive) or comment the line below
usernames: "discobot,john,mike",
// 2- set title or comment the line below
topicTitle: "Title",
// 3- uncomment the line below to set a "template" for PM.
// Not really recommended will
// override any drafts everytime the
// button is pressed
// topicBody: "placeholder content",
// no need to change these
archetypeId: "private_message",
draftKey: Composer.NEW_PRIVATE_MESSAGE_KEY,
});
};
return helper.h(
$ntb_button_helper,
{
className: $ntb_button_class,
title: $ntb_text,
onclick: createPM
},
[helper.h($ntb_icon_helper), helper.h($ntb_label_helper, $ntb_text)]
);
}
});
</script>
Obviously, if you plan on using all three buttons you can reduce the size of the code quite drastically because most of it is shared by all three, but I kept things separate because some might just want to use one and not all three.
What this will do is add a button to the header like so:
Clicking the button will open the composer and the fields will be pre-filled with whatever you chose:
I already left a comment in the code about setting any placeholder content in the body for PMs using this method. It’s not recommended unless you have a very specific template. This will override any previously saved PM drafts everytime you use the button.
That’s why it’s “off” by default in the code above.
I’ve tested this a bit and have not seen any problems. If you encounter anything let me know.
Love it. Worked perfectly. Thanks Joe, you’re awesome!
I noticed the user names are case sensitive. If a username’s case is wrong, the name appears in the recipient list, but the PM won’t send. Suggest you add this to your comments: -
// 1- set recipients (Case Sensitive) or comment the line below
usernames: "discobot,john,mike",
Hi @Johani - thank you, I have implemented this, but a bit too successfully!
Would it be possible to make a new personal message header button appear only selectively for those who have access to personal messaging? New users by default don’t have access to PM so should not see this button…
We have set the site setting (for our TL0, TL1 and TL2 users (who therefor are restricted from personal messaging))
Thanks again,
Hi @jerry0
Yes, that is possible!
One way to do this is to look up the current user’s trust level and use that as a base to determine whether or not to create the PM button.
You would use something like this:
<script type="text/discourse-plugin" version="0.8.18">
// no need to edit these
const container = Discourse.__container__,
controller = container.lookup("controller:application"),
trust = controller.get("currentUser.trust_level");
api.decorateWidget("header-buttons:after", helper => {
// change desired trust level here
if (Discourse.User.current() && trust >= "2") {
// edit these two to your liking
var $ntb_text = "New Personal Message",
$ntb_icon = "heart",
// no need to edit these
$ntb_icon_class = ".fa-" + $ntb_icon,
$ntb_button_class = "btn btn-default btn btn-icon-text",
$ntb_button_helper = "button#new-create-topic-custom",
$ntb_icon_helper =
"i.fa" + $ntb_icon_class + ".d-icon .d-icon-" + $ntb_icon,
$ntb_label_helper = "span.d-button-label";
const createPM = function() {
const Composer = require("discourse/models/composer").default,
composerController = container.lookup("controller:composer");
composerController.open({
action: Composer.PRIVATE_MESSAGE,
// 1- set recipients (Case Sensitive) or comment the line below
usernames: "discobot,john,mike",
// 2- set title or comment the line below
topicTitle: "Title",
// 3- uncomment the line below to set a "template" for PM.
// Not really recommended will
// override any drafts everytime the
// button is pressed
// topicBody: "placeholder content",
// no need to change these
archetypeId: "private_message",
draftKey: Composer.NEW_PRIVATE_MESSAGE_KEY
});
};
return helper.h(
$ntb_button_helper,
{
className: $ntb_button_class,
title: $ntb_text,
onclick: createPM
},
[helper.h($ntb_icon_helper), helper.h($ntb_label_helper, $ntb_text)]
);
}
});
</script>
Well that is fab. I will have to wait to get back from my travels tomorrow but will try it out then. Thanks!
I’ve now tried it out and it works well. Many thanks.
Is it only possible to do this if u are able to code?
Um, no - I really can’t
… just followed the instructions above…
Would it be possible to change the button text for the default + New Topic button based on which category you’re browsing?
Yes, that would also be possible as well. You can use something like this in the header section of a theme component
<script type="text/discourse-plugin" version="0.8">
const i18nTopicLable = I18n.lookup("topic.create");
api.modifyClass("component:create-topic-button", {
didInsertElement: function() {
var button = $(this),
category = button[0].parentView.get("category"),
label = button[0].label,
newTopicLabel = "topic.create",
buttonText = "";
if (category) {
categoryName = category.name;
if (label != newTopicLabel) {
return;
} else {
switch (categoryName) {
case "category1": // category name
buttonText = "category1 text"; // button text
break;
// repeat
case "category2":
buttonText = "category2 text";
break;
// add more above this line
default:
buttonText = i18nTopicLable;
}
$("#create-topic .d-button-label").text(buttonText);
}
}
}
});
</script>
To add new categories, you only need to add this above where it says default
case "category":
buttonText = "text";
break;
If you have a pending draft and the button says “open draft” the script won’t fire.
I’ve created a small preview on theme creator and changed the text for the movies, tech, school, videos and gaming categories
Edit:
@dax informed me that I had missed something in the snippet I posted previously and so I updated it and the preview so be sure to use the latest one @tophee
此功能已停止工作。一种根据类别重命名按钮的新方法已发布在此处:
操作方法:
category-btn-name/locales/en.yml,输入您想使用的各种按钮文本,例如:en:
new_event: 新建事件
new_deadline: 新建截止日期
category-btn-name/javascripts/discourse/api-initializers/initialize-btn-names.js,定义哪些类别使用哪些按钮文本:const TRANSLATION_KEYS = {
"Events": "new_event",
"Calendar": "new_event",
"Deadlines": "new_dealine",
};