Skip to content

Commit 241c4c3

Browse files
committed
up
1 parent e20703a commit 241c4c3

7 files changed

Lines changed: 215 additions & 11 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ Telegram:[@lgc2333](https://t.me/lgc2333)
225225

226226
## 📝 更新日志
227227

228+
### 0.4.1
229+
230+
- 修复插件自定义详情页模板时,功能详情页不会默认继承插件模板的问题
231+
- 新增 `extra["pmn"]["inherit_func_template"]`,插件开发者可将其设为 `False` 关闭功能详情页模板继承
232+
228233
### 0.4.0
229234

230235
- 新增 `plugin:` 资源路径语法,在插件描述、菜单项等支持 Markdown 或 HTML 的文本中引用其他插件的静态资源:

defs/ExternalPluginInfo.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
"default": null,
3434
"title": "Template"
3535
},
36+
"inherit_func_template": {
37+
"default": true,
38+
"title": "Inherit Func Template",
39+
"type": "boolean"
40+
},
3641
"alc_force_enable_detect": {
3742
"default": false,
3843
"title": "Alc Force Enable Detect",
@@ -83,6 +88,7 @@
8388
"hidden": false,
8489
"markdown": false,
8590
"template": null,
91+
"inherit_func_template": true,
8692
"alc_force_enable_detect": false
8793
}
8894
}

docs/development.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ __plugin_meta__ = PluginMetadata(
7272
"hidden": False,
7373
"markdown": True,
7474
"template": "default",
75+
"inherit_func_template": True,
7576
"alc_force_enable_detect": False,
7677
},
7778
"menu_data": [
@@ -89,12 +90,13 @@ __plugin_meta__ = PluginMetadata(
8990

9091
`pmn` 支持以下可选字段:
9192

92-
| 字段 | 类型 | 默认值 | 说明 |
93-
| ------------------------- | ------------- | ------- | --------------------------------------------------- |
94-
| `hidden` | `bool` | `False` | 是否在普通帮助菜单中隐藏 |
95-
| `markdown` | `bool` | `False` | 是否将描述、用法、功能详情按 Markdown 渲染 |
96-
| `template` | `str \| None` | `None` | 为该插件指定详情页模板 |
97-
| `alc_force_enable_detect` | `bool` | `False` | 即使已定义 `menu_data`,也强制启用 Alconna 自动探测 |
93+
| 字段 | 类型 | 默认值 | 说明 |
94+
| ------------------------- | ------------- | ------- | -------------------------------------------------------- |
95+
| `hidden` | `bool` | `False` | 是否在普通帮助菜单中隐藏 |
96+
| `markdown` | `bool` | `False` | 是否将描述、用法、功能详情按 Markdown 渲染 |
97+
| `template` | `str \| None` | `None` | 为该插件指定详情页模板 |
98+
| `inherit_func_template` | `bool` | `True` | 功能项未设置 `pmn_template` 时,功能详情页是否继承该模板 |
99+
| `alc_force_enable_detect` | `bool` | `False` | 即使已定义 `menu_data`,也强制启用 Alconna 自动探测 |
98100

99101
`menu_data` 中每一项对应一个三级菜单功能,必填字段为 `func``trigger_method``trigger_condition``brief_des``detail_des`
100102

@@ -340,7 +342,7 @@ async def render_func_detail(
340342

341343
三个模板注册器互相独立,通常建议使用同一个模板名分别注册首页、插件详情页、功能详情页。用户可通过 `PMN_INDEX_TEMPLATE``PMN_DETAIL_TEMPLATE``PMN_FUNC_DETAIL_TEMPLATE` 设置默认模板。
342344

343-
单个插件也可以通过 `extra["pmn"]["template"]` 指定详情页模板单个功能可以通过 `pmn_template` 指定功能详情页模板。
345+
单个插件也可以通过 `extra["pmn"]["template"]` 指定详情页模板。默认情况下,功能详情页会在功能项未设置 `pmn_template` 时继承该模板;如果插件开发者不希望继承,可以设置 `extra["pmn"]["inherit_func_template"]``False`单个功能可以通过 `pmn_template` 指定功能详情页模板,并且会优先于继承的插件模板
344346

345347
`func_index` 表示当前功能在插件功能列表中的 0 基序号;当功能详情来自 Alconna `-h/--help` 接管时,如果当前命令没有对应的已注册菜单项,PicMenu Next 会临时生成一个功能项,此时 `func_index``None`
346348

nonebot_plugin_picmenu_next/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .data_source import refresh_infos
1212
from .templates import preload_builtin_templates
1313

14-
__version__ = "0.4.0"
14+
__version__ = "0.4.1"
1515
__plugin_meta__ = PluginMetadata(
1616
name="PicMenu Next",
1717
description="新一代的图片帮助插件",

nonebot_plugin_picmenu_next/__main__.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,18 @@ async def render_menu(
311311
func_index, func = r
312312
if alc_detail_des is not None:
313313
func = model_copy(func, update={"detail_des": alc_detail_des})
314+
template = func.template or (
315+
info.pmn.template if info.pmn.inherit_func_template else None
316+
)
314317
return (
315-
await func_detail_templates.get(
316-
func.template,
317-
)(info, info_index, func, func_index, show_hidden, user_can_see_hidden),
318+
await func_detail_templates.get(template)(
319+
info,
320+
info_index,
321+
func,
322+
func_index,
323+
show_hidden,
324+
user_can_see_hidden,
325+
),
318326
info,
319327
func,
320328
)

nonebot_plugin_picmenu_next/data_source/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class PMNData(CompatModel):
7272
hidden: bool = False
7373
markdown: bool = False
7474
template: str | None = None
75+
inherit_func_template: bool = True
7576
alc_force_enable_detect: bool = False
7677

7778

tests/test_alconna_collect.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,188 @@ async def fake_inject(dependent: object) -> Bot: # noqa: ARG001
650650
assert msg.extract_plain_text() == "fallback help"
651651

652652

653+
async def test_func_detail_inherits_plugin_template(
654+
picmenu_plugin: object, # noqa: ARG001
655+
monkeypatch: "pytest.MonkeyPatch",
656+
) -> None:
657+
from nonebot_plugin_alconna.uniseg import UniMessage
658+
from nonebot_plugin_picmenu_next import __main__
659+
from nonebot_plugin_picmenu_next.data_source.models import (
660+
PMDataItem,
661+
PMNData,
662+
PMNPluginInfo,
663+
)
664+
665+
async def render_func_detail(
666+
pmn: PMNData,
667+
func_template: str | None = None,
668+
) -> UniMessage | None:
669+
monkeypatch.setattr(__main__, "resolve_main_mixin", fake_resolve_main)
670+
monkeypatch.setattr(__main__, "resolve_detail_mixin", fake_resolve_detail)
671+
monkeypatch.setattr(
672+
__main__,
673+
"get_infos",
674+
lambda: [
675+
PMNPluginInfo(
676+
name="继承模板插件",
677+
pmn=pmn,
678+
pm_data=[
679+
PMDataItem(
680+
func="继承模板功能",
681+
trigger_method="继承模板功能",
682+
trigger_condition="指令",
683+
brief_des="测试继承插件模板",
684+
detail_des="测试继承插件模板详情",
685+
pmn_template=func_template,
686+
),
687+
],
688+
),
689+
],
690+
)
691+
monkeypatch.setitem(
692+
__main__.func_detail_templates.data,
693+
"default",
694+
default_func_detail,
695+
)
696+
monkeypatch.setitem(
697+
__main__.func_detail_templates.data,
698+
"inherited",
699+
inherited_func_detail,
700+
)
701+
702+
bot = cast("Bot", SimpleNamespace(adapter=SimpleNamespace()))
703+
ev = cast("Event", SimpleNamespace())
704+
705+
msg, _, _ = await __main__.render_menu(
706+
bot,
707+
ev,
708+
q_plugin="1",
709+
q_function="1",
710+
)
711+
return msg
712+
713+
async def fake_resolve_main(infos: list[PMNPluginInfo]) -> list[PMNPluginInfo]:
714+
return infos
715+
716+
async def fake_resolve_detail(info: PMNPluginInfo) -> PMNPluginInfo:
717+
return info
718+
719+
async def default_func_detail(
720+
info: PMNPluginInfo, # noqa: ARG001
721+
info_index: int, # noqa: ARG001
722+
func: PMDataItem, # noqa: ARG001
723+
func_index: int | None, # noqa: ARG001
724+
showing_hidden: bool, # noqa: ARG001
725+
user_can_see_hidden: bool | None, # noqa: ARG001
726+
) -> UniMessage:
727+
return UniMessage("default template")
728+
729+
async def inherited_func_detail(
730+
info: PMNPluginInfo,
731+
info_index: int,
732+
func: PMDataItem,
733+
func_index: int | None,
734+
showing_hidden: bool,
735+
user_can_see_hidden: bool | None,
736+
) -> UniMessage:
737+
assert info.name == "继承模板插件"
738+
assert info_index == 0
739+
assert func.func == "继承模板功能"
740+
assert func_index == 0
741+
assert showing_hidden is False
742+
assert user_can_see_hidden is None
743+
return UniMessage("inherited template")
744+
745+
msg = await render_func_detail(PMNData(template="inherited"))
746+
747+
assert msg is not None
748+
assert msg.extract_plain_text() == "inherited template"
749+
750+
751+
async def test_func_detail_can_disable_plugin_template_inheritance(
752+
picmenu_plugin: object, # noqa: ARG001
753+
monkeypatch: "pytest.MonkeyPatch",
754+
) -> None:
755+
from nonebot_plugin_alconna.uniseg import UniMessage
756+
from nonebot_plugin_picmenu_next import __main__
757+
from nonebot_plugin_picmenu_next.data_source.models import (
758+
PMDataItem,
759+
PMNData,
760+
PMNPluginInfo,
761+
)
762+
763+
async def fake_resolve_main(infos: list[PMNPluginInfo]) -> list[PMNPluginInfo]:
764+
return infos
765+
766+
async def fake_resolve_detail(info: PMNPluginInfo) -> PMNPluginInfo:
767+
return info
768+
769+
async def default_func_detail(
770+
info: PMNPluginInfo, # noqa: ARG001
771+
info_index: int, # noqa: ARG001
772+
func: PMDataItem, # noqa: ARG001
773+
func_index: int | None, # noqa: ARG001
774+
showing_hidden: bool, # noqa: ARG001
775+
user_can_see_hidden: bool | None, # noqa: ARG001
776+
) -> UniMessage:
777+
return UniMessage("default template")
778+
779+
async def inherited_func_detail(
780+
info: PMNPluginInfo, # noqa: ARG001
781+
info_index: int, # noqa: ARG001
782+
func: PMDataItem, # noqa: ARG001
783+
func_index: int | None, # noqa: ARG001
784+
showing_hidden: bool, # noqa: ARG001
785+
user_can_see_hidden: bool | None, # noqa: ARG001
786+
) -> UniMessage:
787+
return UniMessage("inherited template")
788+
789+
monkeypatch.setattr(__main__, "resolve_main_mixin", fake_resolve_main)
790+
monkeypatch.setattr(__main__, "resolve_detail_mixin", fake_resolve_detail)
791+
monkeypatch.setattr(
792+
__main__,
793+
"get_infos",
794+
lambda: [
795+
PMNPluginInfo(
796+
name="禁用继承插件",
797+
pmn=PMNData(template="inherited", inherit_func_template=False),
798+
pm_data=[
799+
PMDataItem(
800+
func="禁用继承功能",
801+
trigger_method="禁用继承功能",
802+
trigger_condition="指令",
803+
brief_des="测试关闭继承插件模板",
804+
detail_des="测试关闭继承插件模板详情",
805+
),
806+
],
807+
),
808+
],
809+
)
810+
monkeypatch.setitem(
811+
__main__.func_detail_templates.data,
812+
"default",
813+
default_func_detail,
814+
)
815+
monkeypatch.setitem(
816+
__main__.func_detail_templates.data,
817+
"inherited",
818+
inherited_func_detail,
819+
)
820+
821+
bot = cast("Bot", SimpleNamespace(adapter=SimpleNamespace()))
822+
ev = cast("Event", SimpleNamespace())
823+
824+
msg, _, _ = await __main__.render_menu(
825+
bot,
826+
ev,
827+
q_plugin="1",
828+
q_function="1",
829+
)
830+
831+
assert msg is not None
832+
assert msg.extract_plain_text() == "default template"
833+
834+
653835
async def test_help_extension_generates_current_command_when_visible_func_missing(
654836
picmenu_plugin: object, # noqa: ARG001
655837
monkeypatch: "pytest.MonkeyPatch",

0 commit comments

Comments
 (0)