mirror of
https://github.com/bs-community/blessing-skin-server.git
synced 2025-02-23 14:59:07 +08:00
Detect Readme of plugin automatically
This commit is contained in:
parent
8a66a70ced
commit
66becb27d0
@ -24,6 +24,25 @@ class PluginController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function readme(PluginManager $plugins, $name)
|
||||
{
|
||||
$plugin = $plugins->get($name);
|
||||
if (empty($plugin)) {
|
||||
return abort(404, trans('admin.plugins.operations.no-readme-notice'));
|
||||
}
|
||||
|
||||
$readmePath = $plugin->getReadme();
|
||||
if (empty($readmePath)) {
|
||||
return abort(404, trans('admin.plugins.operations.no-readme-notice'));
|
||||
}
|
||||
|
||||
$title = $plugin->title;
|
||||
$path = $plugin->getPath().'/'.$readmePath;
|
||||
$content = resolve('parsedown')->text(file_get_contents($path));
|
||||
|
||||
return view('admin.plugin.readme', compact('content', 'title'));
|
||||
}
|
||||
|
||||
public function manage(Request $request, PluginManager $plugins)
|
||||
{
|
||||
$name = $request->input('name');
|
||||
@ -95,6 +114,7 @@ class PluginController extends Controller
|
||||
'version' => $plugin->version,
|
||||
'url' => $plugin->url,
|
||||
'enabled' => $plugin->isEnabled(),
|
||||
'readme' => (bool) $plugin->getReadme(),
|
||||
'config' => $plugin->hasConfig(),
|
||||
'dependencies' => [
|
||||
'all' => $plugin->require,
|
||||
|
@ -9,6 +9,12 @@ use Illuminate\Support\Str;
|
||||
|
||||
class Plugin
|
||||
{
|
||||
const README_FILES = [
|
||||
'README.md',
|
||||
'readme.md',
|
||||
'README.MD',
|
||||
];
|
||||
|
||||
/**
|
||||
* The full directory of this plugin.
|
||||
*
|
||||
@ -58,6 +64,13 @@ class Plugin
|
||||
return "$baseUrl/{$this->name}/assets/$relativeUri?v=".$this->version;
|
||||
}
|
||||
|
||||
public function getReadme()
|
||||
{
|
||||
return Arr::first(self::README_FILES, function ($filename) {
|
||||
return file_exists($this->path.'/'.$filename);
|
||||
});
|
||||
}
|
||||
|
||||
public function hasConfig(): bool
|
||||
{
|
||||
return $this->hasConfigClass() || $this->hasConfigView();
|
||||
|
@ -11,34 +11,42 @@
|
||||
<template #table-row="props">
|
||||
<span v-if="props.column.field === 'title'">
|
||||
<strong>{{ props.formattedRow[props.column.field] }}</strong>
|
||||
<div v-if="props.row.enabled" class="actions">
|
||||
<template v-if="props.row.config">
|
||||
<div class="actions">
|
||||
<template v-if="props.row.readme">
|
||||
<a
|
||||
v-t="'admin.configurePlugin'"
|
||||
:href="`${baseUrl}/admin/plugins/readme/${props.row.name}`"
|
||||
class="text-primary"
|
||||
:href="`${baseUrl}/admin/plugins/config/${props.row.name}`"
|
||||
/> |
|
||||
>{{ $t('admin.pluginReadme') }}</a> |
|
||||
</template>
|
||||
<template v-if="props.row.enabled" class="actions">
|
||||
<template v-if="props.row.config">
|
||||
<a
|
||||
v-t="'admin.configurePlugin'"
|
||||
class="text-primary"
|
||||
:href="`${baseUrl}/admin/plugins/config/${props.row.name}`"
|
||||
/> |
|
||||
</template>
|
||||
<a
|
||||
v-t="'admin.disablePlugin'"
|
||||
href="#"
|
||||
class="text-primary"
|
||||
@click="disablePlugin(props.row)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else class="actions">
|
||||
<a
|
||||
v-t="'admin.enablePlugin'"
|
||||
href="#"
|
||||
class="text-primary"
|
||||
@click="enablePlugin(props.row)"
|
||||
/> |
|
||||
<a
|
||||
v-t="'admin.deletePlugin'"
|
||||
href="#"
|
||||
class="text-danger"
|
||||
@click="deletePlugin(props.row)"
|
||||
/>
|
||||
</template>
|
||||
<a
|
||||
v-t="'admin.disablePlugin'"
|
||||
href="#"
|
||||
class="text-primary"
|
||||
@click="disablePlugin(props.row)"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="actions">
|
||||
<a
|
||||
v-t="'admin.enablePlugin'"
|
||||
href="#"
|
||||
class="text-primary"
|
||||
@click="enablePlugin(props.row)"
|
||||
/> |
|
||||
<a
|
||||
v-t="'admin.deletePlugin'"
|
||||
href="#"
|
||||
class="text-danger"
|
||||
@click="deletePlugin(props.row)"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
<span v-else-if="props.column.field === 'description'">
|
||||
|
@ -169,3 +169,19 @@ test('delete plugin', async () => {
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('No data')
|
||||
})
|
||||
|
||||
test('readme link', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
readme: true,
|
||||
dependencies: { all: {}, unsatisfied: {} },
|
||||
},
|
||||
])
|
||||
const wrapper = mount(Plugins)
|
||||
await flushPromises()
|
||||
|
||||
const link = wrapper.find('.actions > a:nth-child(1)')
|
||||
expect(link.text()).toContain('admin.pluginReadme')
|
||||
expect(link.attributes('href')).toBe('/admin/plugins/readme/a')
|
||||
})
|
||||
|
@ -116,6 +116,7 @@ plugins:
|
||||
description: Description
|
||||
author: Author
|
||||
version: Version
|
||||
readme: Read Me
|
||||
dependencies: Dependencies
|
||||
|
||||
operations:
|
||||
@ -129,6 +130,7 @@ plugins:
|
||||
disabled: :plugin has been disabled.
|
||||
deleted: The plugin was deleted successfully.
|
||||
no-config-notice: The plugin is not installed or doesn't provide a configuration page.
|
||||
no-readme-notice: The plugin doesn't contain a readme file.
|
||||
not-found: No such plugin.
|
||||
|
||||
market:
|
||||
|
@ -276,6 +276,7 @@ admin:
|
||||
pluginAuthor: Author
|
||||
pluginVersion: Version
|
||||
pluginName: Name
|
||||
pluginReadme: Read Me
|
||||
pluginDescription: Description
|
||||
pluginDependencies: Dependencies
|
||||
installPlugin: Install
|
||||
|
@ -11,6 +11,7 @@
|
||||
- Added support of customizing UI text.
|
||||
- Spanish support (Greatly thanks [@poopingpenis](https://github.com/poopingpenis))
|
||||
- Brand new website theme color settings.
|
||||
- Detect Readme file of plugin automatically.
|
||||
|
||||
## Tweaked
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
- 支持自定义 UI 文本
|
||||
- 西班牙语支持(感谢 [@poopingpenis](https://github.com/poopingpenis))
|
||||
- 全新的站点配色设置
|
||||
- 自动识别插件的说明文件
|
||||
|
||||
## 调整
|
||||
|
||||
|
17
resources/views/admin/plugin/readme.twig
Normal file
17
resources/views/admin/plugin/readme.twig
Normal file
@ -0,0 +1,17 @@
|
||||
{% extends 'admin.base' %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card card-secondary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">{{ trans('admin.plugins.readme') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">{{ content|raw }}</div>
|
||||
<div class="card-footer">
|
||||
<button class="btn bg-primary" onclick="history.back()">
|
||||
{{ trans('general.back') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -151,6 +151,7 @@ Route::group(['middleware' => ['authorize', 'admin'], 'prefix' => 'admin'], func
|
||||
Route::view('/manage', 'admin.plugins');
|
||||
Route::post('/manage', 'PluginController@manage');
|
||||
Route::any('/config/{name}', 'PluginController@config');
|
||||
Route::get('/readme/{name}', 'PluginController@readme');
|
||||
|
||||
Route::view('/market', 'admin.market');
|
||||
Route::get('/market-data', 'MarketController@marketData');
|
||||
|
@ -90,6 +90,37 @@ class PluginControllerTest extends TestCase
|
||||
option(['plugins_enabled' => '[]']);
|
||||
}
|
||||
|
||||
public function testReadme()
|
||||
{
|
||||
$this->mock(PluginManager::class, function ($mock) {
|
||||
$mock->shouldReceive('getEnabledPlugins')->andReturn(collect());
|
||||
|
||||
$mock->shouldReceive('get')
|
||||
->with('fake1')
|
||||
->once()
|
||||
->andReturn(null);
|
||||
|
||||
$mock->shouldReceive('get')
|
||||
->with('fake2')
|
||||
->once()
|
||||
->andReturn(new Plugin(storage_path(), []));
|
||||
|
||||
$mock->shouldReceive('get')
|
||||
->with('fake3')
|
||||
->once()
|
||||
->andReturn(new Plugin(base_path(), ['title' => '']));
|
||||
});
|
||||
|
||||
// No such plugin.
|
||||
$this->get('/admin/plugins/readme/fake1')->assertNotFound();
|
||||
|
||||
// Plugin doesn't have readme.
|
||||
$this->get('/admin/plugins/readme/fake2')->assertNotFound();
|
||||
|
||||
// Ok.
|
||||
$this->get('/admin/plugins/readme/fake3')->assertSuccessful();
|
||||
}
|
||||
|
||||
public function testManage()
|
||||
{
|
||||
$this->mock(PluginManager::class, function ($mock) {
|
||||
@ -255,6 +286,7 @@ class PluginControllerTest extends TestCase
|
||||
'url',
|
||||
'enabled',
|
||||
'config',
|
||||
'readme',
|
||||
'dependencies',
|
||||
],
|
||||
]);
|
||||
|
Loading…
Reference in New Issue
Block a user