Hello Discourse Team!
I am using the discourse CLI Discourse Theme CLI (console app to help you build themes) and the plugin API A new versioned API for client side plugins to help me create my theme.
I have added a custom header in the header.html file. On mobile, I was hoping to create a hamburger menu that functions like discourse’s hamburger
But has completely different menu contents.
I could create the hamburger and menu with my knowledge of css/html/js. But I was hoping for a way to use the functionality that discourse has already implemented (opening, closing, etc…).
Any suggestions on how to achieve this?
I thought maybe I would be able to extend the widget for the current navigation, change the settings, then attach it to the html I have written for my nav. But the connectors seemed to be predefined, and I wasnt sure how to connect my widget to my html. This might not be the right direction at all either…
2 个赞
Okay, so I think I have a better understanding on what I am trying to do.
I would like to create a connector where I can connect to one of the elements that I have added to the page.
I’m guessing this isn’t possible???
The plugin API (https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11 ) has api.registerConnectorClass but I cannot seem to figure out how to connect this to my custom element.
simon
2018 年4 月 18 日 22:47
4
The Brand Header might give you some ideas about how to approach this. You can find its code here: GitHub - discourse/discourse-brand-header: Brand header theme component for Discourse . It only displays a hamburger menu in mobile mode. You can get the mobile view on a desktop by appending
?mobile_view=1 to your forum’s URL.
10 个赞
This is slightly rough but should get you 99% of the way there when it comes to having an additional menu item with a dropdown panel. Calling this one a pizza menu . Add this to your header.html file.
<script type="text/discourse-plugin" version="0.8">
api.createWidget('pizza-menu', {
tagName: 'div.pizza-panel',
panelContents() {
return "hello world";
},
html() {
return this.attach('menu-panel', {
contents: () => this.panelContents()
});
},
clickOutside() {
this.sendWidgetAction('togglePizza');
}
});
api.decorateWidget('header-icons:after', function(helper) {
const headerState = helper.widget.parentWidget.state;
let contents = [];
contents.push(helper.attach('header-dropdown', {
title: 'pizza-menu',
icon: 'cutlery',
active: headerState.pizzaVisible,
iconId: 'toggle-pizza-menu',
action: 'togglePizza',
}));
if (headerState.pizzaVisible) {
contents.push(helper.attach('pizza-menu'));
}
return contents;
});
api.attachWidgetAction('header', 'togglePizza', function() {
this.state.pizzaVisible = !this.state.pizzaVisible;
});
</script>
20 个赞
Yes! This is very close!
My only concern was the connect part:
What if I wanted to add the pizza menu to a custom HTML element (defined in common/head_tag.html)?
Ah ok in that case you’re looking at something more like what @simon mentioned in the brand header theme component, I was attaching the action to the existing header widget… the brand header adds it to a new one. The new widget here w/ toggleHamburger:
api.createWidget('brand-header', {
tagName: 'header.b-header.clearfix',
buildKey: () => `header`,
defaultState() {
let states = {
hamburgerVisible: false
};
return states;
},
toggleHamburger() {
this.state.hamburgerVisible = !this.state.hamburgerVisible;
},
and then the action is added to an HTML element in another widget here
api.createWidget('brand-header-icons', {
tagName: 'ul.icons.clearfix',
buildAttributes() {
return { role: 'navigation' };
},
html(attrs) {
const hamburger = this.attach('header-dropdown', {
title: 'hamburger_brand_menu',
icon: 'bars',
iconId: 'toggle-hamburger-brand-menu',
active: attrs.hamburgerVisible,
action: 'toggleHamburger'
});
const icons = [hamburger];
return icons;
},
});
8 个赞
Thank you for this code. Can you point me in the right direction on filling out the panelContents? I see some indication , but not sure how it all links together.
Queth
(Q)
2020 年1 月 2 日 17:55
9
你好!我知道这是一个旧话题,但这几乎就是我正在寻找或尝试做的事情。因此我在此发帖(而不是创建新话题)。请理解,我并非开发者,不了解插件的工作原理,也不会编写 JavaScript,但我懂得如何复制粘贴代码。
我试图在下拉菜单中添加一个聊天室的登录功能。也就是说,我想要一个“聊天”图标,下拉菜单中包含一个输入框、一个提交按钮,以及一些帮助文本或指向帮助页面的链接。
我能否修改您的代码,将“餐具”图标替换为“聊天”图标?具体该如何操作?
其次,我该如何插入 HTML 代码,而不是显示“你好,世界”这句话?(基本上就是如何在那里输入 HTML?)
非常感谢您的帮助!
1 个赞
ngets
(ngets)
2020 年7 月 2 日 09:34
10
关于 Queth 的帖子,是否可以在下拉面板中 FAQ 之前插入一个额外的链接?
这个组件应该可行。只需将自定义链接移到 FAQ 之前即可。
https://meta.discourse.org/t/custom-hamburger-menu-links/87644/41
2 个赞
哈哈,真巧,我也在看完全相同的内容。我认为最好的方法是重新打开汉堡菜单组件并覆盖 html 方法。
this.attach("menu-links", {
name: "footer-links",
omitRule: true,
contents: () => this.footerLinks(prioritizeFaq, faqUrl)
})
);
return results;
},
html() {
return this.attach("menu-panel", {
contents: () => this.panelContents(),
maxWidth: this.settings.maxWidth
});
},
clickOutsideMobile(e) {
const $centeredElement = $(document.elementFromPoint(e.clientX, e.clientY));
if (
$centeredElement.parents(".panel").length &&
我会在 FAQ 项目之前 unshift 我的组件。我还没测试是否可行,但这将是我的思路
看起来在这里是有效的
api.reopenWidget("hamburger-menu", {
html() {
let conti = this.panelContents()
conti.unshift(h('div',[h('span','描述:'),this.attach('widget-dropdown',
{id: "from", translatedLabel: "bla",onChange: "changeaction",
content: [
{ id: 1, label: "foo.bar" },
{ id: 2, translatedLabel: "FooBar" },
{ id: 3, label: "foo.baz", icon: "times" },
{ id: 4, html: "<b>foo</b>" },
],
options: {bodyClass: "lang-drop-body"}
})]))
return this.attach("menu-panel", {
contents: () => conti,
maxWidth: this.settings.maxWidth
});
},
});
例如,我添加了一个下拉菜单。
干杯
4 个赞
ngets
(ngets)
2020 年7 月 10 日 05:38
12
你好,我该如何将其放在搜索图标右侧?又该如何在 panelContents 中添加自定义 HTML?
1 个赞