nodebb-plugin-fab-cards 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +9 -44
- package/commitlint.config.js +26 -0
- package/eslint.config.mjs +10 -0
- package/languages/de/quickstart.json +3 -0
- package/languages/en-GB/quickstart.json +3 -0
- package/languages/en-US/quickstart.json +3 -0
- package/lib/controllers.js +20 -0
- package/library.js +74 -121
- package/package.json +36 -19
- package/plugin.json +14 -10
- package/public/lib/acp-main.js +18 -0
- package/public/lib/admin.js +55 -0
- package/public/lib/main.js +33 -0
- package/public/lib/quickstart.js +15 -0
- package/renovate.json +5 -0
- package/scss/quickstart.scss +1 -0
- package/static/samplefile.html +8 -0
- package/templates/admin/plugins/quickstart/partials/sorted-list/form.tpl +10 -0
- package/templates/admin/plugins/quickstart/partials/sorted-list/item.tpl +12 -0
- package/templates/admin/plugins/quickstart.tpl +68 -0
- package/templates/quickstart.tpl +7 -0
- package/test/.eslintrc +9 -0
- package/test/index.js +41 -0
- package/.github/workflows/publish.yml +0 -21
- package/data/cards-index.json +0 -14358
- package/docker-compose.yml +0 -50
- package/public/css/style.css +0 -24
- package/public/lib/client.js +0 -121
- package/scripts/build-card-index.js +0 -103
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 NodeBB Inc. <sales@nodebb.org>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,52 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Quickstart Plugin for NodeBB
|
|
2
2
|
|
|
3
|
-
A NodeBB
|
|
3
|
+
A starter kit for quickly creating NodeBB plugins. Comes with a pre-setup SCSS file, server side JS script with an `static:app.load` hook, and a client-side script. Most plugins need at least one of the above, so this ought to save you some time. For a full list of hooks have a look at our [wiki page](https://github.com/NodeBB/NodeBB/wiki/Hooks), and for more information about creating plugins please visit our [documentation portal](https://docs.nodebb.org/).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Fork this or copy it, and using your favourite text editor find and replace all instances of `nodebb-plugin-fab-cards` with `nodebb-plugin-your-plugins-name`. Change the author's name in the LICENSE and package.json files.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- Converts matches to links such as `https://cards.fabtcg.com/card/command-and-conquer-1/`
|
|
9
|
-
- Opens links in a new tab
|
|
10
|
-
- Shows preview image on hover (desktop) and first touch (mobile)
|
|
11
|
-
- Uses a static generated card index (`data/cards-index.json`) for fast runtime lookups
|
|
7
|
+
## Hello World
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
Really simple, just edit `public/lib/main.js` and paste in `console.log('hello world');`, and that's it!
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
## Installation
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
- Build script: `scripts/build-card-index.js`
|
|
13
|
+
npm install nodebb-plugin-fab-cards
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
## Screenshots
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
npm install
|
|
24
|
-
npm run build:cards
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Installation in NodeBB
|
|
28
|
-
|
|
29
|
-
In your plugin folder:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm link
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
In your NodeBB folder:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npm link nodebb-plugin-fab-cards
|
|
39
|
-
./nodebb build
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Then activate `FAB Cards Auto-Link` in ACP (`/admin/extend/plugins`).
|
|
43
|
-
|
|
44
|
-
## Local development NodeBB setup
|
|
45
|
-
|
|
46
|
-
A local setup guide is included in [dev/README.md](dev/README.md).
|
|
47
|
-
|
|
48
|
-
## Notes
|
|
49
|
-
|
|
50
|
-
- The parser only transforms posts for `type=default` rendering.
|
|
51
|
-
- Existing links/code blocks are ignored to avoid corrupting content.
|
|
52
|
-
- Re-run `npm run build:cards` periodically to refresh card data.
|
|
17
|
+
Don't forget to add screenshots!
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
extends: ['@commitlint/config-angular'],
|
|
5
|
+
rules: {
|
|
6
|
+
'header-max-length': [1, 'always', 72],
|
|
7
|
+
'type-enum': [
|
|
8
|
+
2,
|
|
9
|
+
'always',
|
|
10
|
+
[
|
|
11
|
+
'breaking',
|
|
12
|
+
'build',
|
|
13
|
+
'chore',
|
|
14
|
+
'ci',
|
|
15
|
+
'docs',
|
|
16
|
+
'feat',
|
|
17
|
+
'fix',
|
|
18
|
+
'perf',
|
|
19
|
+
'refactor',
|
|
20
|
+
'revert',
|
|
21
|
+
'style',
|
|
22
|
+
'test',
|
|
23
|
+
],
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Controllers = module.exports;
|
|
4
|
+
|
|
5
|
+
Controllers.renderAdminPage = function (req, res/* , next */) {
|
|
6
|
+
/*
|
|
7
|
+
Make sure the route matches your path to template exactly.
|
|
8
|
+
|
|
9
|
+
If your route was:
|
|
10
|
+
myforum.com/some/complex/route
|
|
11
|
+
your template should be:
|
|
12
|
+
templates/some/complex/route.tpl
|
|
13
|
+
and you would render it like so:
|
|
14
|
+
res.render('some/complex/route');
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
res.render('admin/plugins/quickstart', {
|
|
18
|
+
title: 'Quick Start',
|
|
19
|
+
});
|
|
20
|
+
};
|
package/library.js
CHANGED
|
@@ -1,135 +1,88 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const nconf = require.main.require('nconf');
|
|
4
|
+
const winston = require.main.require('winston');
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const CARD_HOST = 'https://cards.fabtcg.com';
|
|
6
|
+
const meta = require.main.require('./src/meta');
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
let cardMatcher = null;
|
|
8
|
+
const controllers = require('./lib/controllers');
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
if (cardData) {
|
|
14
|
-
return cardData;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
cardData = require(CARD_INDEX_PATH);
|
|
18
|
-
const cardNames = Object.keys(cardData.cards || {});
|
|
19
|
-
|
|
20
|
-
if (!cardNames.length) {
|
|
21
|
-
cardMatcher = null;
|
|
22
|
-
return cardData;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const escaped = cardNames
|
|
26
|
-
.sort((first, second) => second.length - first.length)
|
|
27
|
-
.map(escapeRegExp);
|
|
28
|
-
|
|
29
|
-
cardMatcher = new RegExp(`(^|[^\\p{L}\\p{N}])(${escaped.join('|')})(?=$|[^\\p{L}\\p{N}])`, 'giu');
|
|
30
|
-
return cardData;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function normalize(input) {
|
|
34
|
-
return String(input || '')
|
|
35
|
-
.normalize('NFKC')
|
|
36
|
-
.toLowerCase()
|
|
37
|
-
.replace(/\s+/g, ' ')
|
|
38
|
-
.trim();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function escapeRegExp(value) {
|
|
42
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function escapeHtml(value) {
|
|
46
|
-
return String(value)
|
|
47
|
-
.replace(/&/g, '&')
|
|
48
|
-
.replace(/"/g, '"')
|
|
49
|
-
.replace(/</g, '<')
|
|
50
|
-
.replace(/>/g, '>');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function shouldSkipNode(node) {
|
|
54
|
-
const parentTag = node.parent && node.parent.tagName ? node.parent.tagName.toLowerCase() : '';
|
|
55
|
-
return ['a', 'code', 'pre', 'script', 'style', 'textarea'].includes(parentTag);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function linkifyText(text, cards) {
|
|
59
|
-
if (!cardMatcher || !text || !text.trim()) {
|
|
60
|
-
return text;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
cardMatcher.lastIndex = 0;
|
|
64
|
-
return text.replace(cardMatcher, (fullMatch, prefix, cardName) => {
|
|
65
|
-
const normalized = normalize(cardName);
|
|
66
|
-
const card = cards[normalized];
|
|
67
|
-
|
|
68
|
-
if (!card) {
|
|
69
|
-
return fullMatch;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const href = `${CARD_HOST}${card.url}`;
|
|
73
|
-
const safeName = escapeHtml(card.name || cardName);
|
|
74
|
-
const safeImage = escapeHtml(card.image || '');
|
|
75
|
-
const safeHref = escapeHtml(href);
|
|
76
|
-
|
|
77
|
-
return `${prefix}<a class="fab-card-link" href="${safeHref}" target="_blank" rel="noopener noreferrer" data-fab-card-name="${safeName}" data-fab-card-image="${safeImage}">${cardName}</a>`;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function processNode($, node, cards) {
|
|
82
|
-
if (!node) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (node.type === 'text' && !shouldSkipNode(node)) {
|
|
87
|
-
const original = node.data || '';
|
|
88
|
-
const replaced = linkifyText(original, cards);
|
|
89
|
-
if (replaced !== original) {
|
|
90
|
-
$(node).replaceWith(replaced);
|
|
91
|
-
}
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (node.children && node.children.length) {
|
|
96
|
-
node.children.slice().forEach((child) => processNode($, child, cards));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
10
|
+
const routeHelpers = require.main.require('./src/routes/helpers');
|
|
99
11
|
|
|
100
12
|
const plugin = {};
|
|
101
13
|
|
|
102
|
-
plugin.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
14
|
+
plugin.init = async (params) => {
|
|
15
|
+
const { router /* , middleware , controllers */ } = params;
|
|
16
|
+
|
|
17
|
+
// Settings saved in the plugin settings can be retrieved via settings methods
|
|
18
|
+
const { setting1, setting2 } = await meta.settings.get('quickstart');
|
|
19
|
+
if (setting1) {
|
|
20
|
+
console.log(setting2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* We create two routes for every view. One API call, and the actual route itself.
|
|
25
|
+
* Use the `setupPageRoute` helper and NodeBB will take care of everything for you.
|
|
26
|
+
*
|
|
27
|
+
* Other helpers include `setupAdminPageRoute` and `setupAPIRoute`
|
|
28
|
+
* */
|
|
29
|
+
routeHelpers.setupPageRoute(router, '/quickstart', [(req, res, next) => {
|
|
30
|
+
winston.info(`[plugins/quickstart] In middleware. This argument can be either a single middleware or an array of middlewares`);
|
|
31
|
+
setImmediate(next);
|
|
32
|
+
}], (req, res) => {
|
|
33
|
+
winston.info(`[plugins/quickstart] Navigated to ${nconf.get('relative_path')}/quickstart`);
|
|
34
|
+
res.render('quickstart', { uid: req.uid });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/quickstart', controllers.renderAdminPage);
|
|
38
|
+
};
|
|
121
39
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
40
|
+
/**
|
|
41
|
+
* If you wish to add routes to NodeBB's RESTful API, listen to the `static:api.routes` hook.
|
|
42
|
+
* Define your routes similarly to above, and allow core to handle the response via the
|
|
43
|
+
* built-in helpers.formatApiResponse() method.
|
|
44
|
+
*
|
|
45
|
+
* In this example route, the `ensureLoggedIn` middleware is added, which means a valid login
|
|
46
|
+
* session or bearer token (which you can create via ACP > Settings > API Access) needs to be
|
|
47
|
+
* passed in.
|
|
48
|
+
*
|
|
49
|
+
* To call this example route:
|
|
50
|
+
* curl -X GET \
|
|
51
|
+
* http://example.org/api/v3/plugins/quickstart/test \
|
|
52
|
+
* -H "Authorization: Bearer some_valid_bearer_token"
|
|
53
|
+
*
|
|
54
|
+
* Will yield the following response JSON:
|
|
55
|
+
* {
|
|
56
|
+
* "status": {
|
|
57
|
+
* "code": "ok",
|
|
58
|
+
* "message": "OK"
|
|
59
|
+
* },
|
|
60
|
+
* "response": {
|
|
61
|
+
* "foobar": "test"
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
*/
|
|
65
|
+
plugin.addRoutes = async ({ router, middleware, helpers }) => {
|
|
66
|
+
const middlewares = [
|
|
67
|
+
middleware.ensureLoggedIn, // use this if you want only registered users to call this route
|
|
68
|
+
// middleware.admin.checkPrivileges, // use this to restrict the route to administrators
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
routeHelpers.setupApiRoute(router, 'get', '/quickstart/:param1', middlewares, (req, res) => {
|
|
72
|
+
helpers.formatApiResponse(200, res, {
|
|
73
|
+
foobar: req.params.param1,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
};
|
|
125
77
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
78
|
+
plugin.addAdminNavigation = (header) => {
|
|
79
|
+
header.plugins.push({
|
|
80
|
+
route: '/plugins/quickstart',
|
|
81
|
+
icon: 'fa-tint',
|
|
82
|
+
name: 'Quickstart',
|
|
83
|
+
});
|
|
130
84
|
|
|
131
|
-
|
|
132
|
-
return payload;
|
|
85
|
+
return header;
|
|
133
86
|
};
|
|
134
87
|
|
|
135
88
|
module.exports = plugin;
|
package/package.json
CHANGED
|
@@ -1,32 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-fab-cards",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "A starter kit for quickly creating NodeBB plugins",
|
|
5
5
|
"main": "library.js",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/nodebb/nodebb-plugin-fab-cards"
|
|
8
9
|
},
|
|
9
10
|
"keywords": [
|
|
10
11
|
"nodebb",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"plugin",
|
|
13
|
+
"quickstart",
|
|
14
|
+
"shell"
|
|
14
15
|
],
|
|
16
|
+
"husky": {
|
|
17
|
+
"hooks": {
|
|
18
|
+
"pre-commit": "lint-staged",
|
|
19
|
+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"lint-staged": {
|
|
23
|
+
"*.js": [
|
|
24
|
+
"eslint --fix",
|
|
25
|
+
"git add"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
15
28
|
"license": "MIT",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/nodebb/nodebb-plugin-fab-cards/issues"
|
|
18
31
|
},
|
|
32
|
+
"readmeFilename": "README.md",
|
|
19
33
|
"nbbpm": {
|
|
20
|
-
"compatibility": "^
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {},
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/braaar/nodebb-plugin-fab-cards.git"
|
|
34
|
+
"compatibility": "^3.2.0"
|
|
26
35
|
},
|
|
27
36
|
"author": "braaar",
|
|
28
|
-
"
|
|
29
|
-
|
|
37
|
+
"homepage": "https://github.com/braaar/nodebb-plugin-fab-cards#readme",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@commitlint/cli": "20.4.2",
|
|
40
|
+
"@commitlint/config-angular": "20.4.2",
|
|
41
|
+
"eslint": "10.0.1",
|
|
42
|
+
"eslint-config-nodebb": "2.0.1",
|
|
43
|
+
"husky": "9.1.7",
|
|
44
|
+
"lint-staged": "16.2.7"
|
|
30
45
|
},
|
|
31
|
-
"
|
|
32
|
-
|
|
46
|
+
"scripts": {
|
|
47
|
+
"lint": "eslint ."
|
|
48
|
+
}
|
|
49
|
+
}
|
package/plugin.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "nodebb-plugin-fab-cards",
|
|
3
|
-
"
|
|
4
|
-
"description": "Automatically links Flesh and Blood card names and shows card previews.",
|
|
5
|
-
"url": "https://github.com/fabtcg/nodebb-plugin-fab-cards",
|
|
3
|
+
"url": "https://github.com/NodeBB/nodebb-plugin-fab-cards",
|
|
6
4
|
"library": "./library.js",
|
|
7
5
|
"hooks": [
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
6
|
+
{ "hook": "static:app.load", "method": "init" },
|
|
7
|
+
{ "hook": "static:api.routes", "method": "addRoutes" },
|
|
8
|
+
{ "hook": "filter:admin.header.build", "method": "addAdminNavigation" }
|
|
12
9
|
],
|
|
13
10
|
"staticDirs": {
|
|
14
|
-
"
|
|
11
|
+
"static": "./static"
|
|
15
12
|
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
13
|
+
"scss": ["scss/quickstart.scss"],
|
|
14
|
+
"scripts": ["public/lib/main.js"],
|
|
15
|
+
"acpScripts": ["public/lib/acp-main.js"],
|
|
16
|
+
"modules": {
|
|
17
|
+
"../client/quickstart.js": "./public/lib/quickstart.js",
|
|
18
|
+
"../admin/plugins/quickstart.js": "./public/lib/admin.js"
|
|
19
|
+
},
|
|
20
|
+
"templates": "templates",
|
|
21
|
+
"languages": "languages"
|
|
18
22
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
$(document).ready(function () {
|
|
4
|
+
/*
|
|
5
|
+
This file shows how admin page client-side javascript can be included via a plugin.
|
|
6
|
+
If you check `plugin.json`, you'll see that this file is listed under "acpScripts".
|
|
7
|
+
That array tells NodeBB which files to bundle into the minified javascript
|
|
8
|
+
that is served to the end user.
|
|
9
|
+
|
|
10
|
+
Some events you can elect to listen for:
|
|
11
|
+
|
|
12
|
+
$(document).ready(); Fired when the DOM is ready
|
|
13
|
+
$(window).on('action:ajaxify.end', function(data) { ... }); "data" contains "url"
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
console.log('nodebb-plugin-fab-cards: acp-loaded');
|
|
17
|
+
// Note how this is shown in the console on the first load of every page in the ACP
|
|
18
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
This file is located in the "modules" block of plugin.json
|
|
5
|
+
It is only loaded when the user navigates to /admin/plugins/quickstart page
|
|
6
|
+
It is not bundled into the min file that is served on the first load of the page.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { save, load } from 'settings';
|
|
10
|
+
import * as uploader from 'uploader';
|
|
11
|
+
|
|
12
|
+
export function init() {
|
|
13
|
+
handleSettingsForm();
|
|
14
|
+
setupUploader();
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function handleSettingsForm() {
|
|
18
|
+
load('quickstart', $('.quickstart-settings'), function () {
|
|
19
|
+
setupColorInputs();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
$('#save').on('click', () => {
|
|
23
|
+
save('quickstart', $('.quickstart-settings')); // pass in a function in the 3rd parameter to override the default success/failure handler
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function setupColorInputs() {
|
|
28
|
+
var colorInputs = $('[data-settings="colorpicker"]');
|
|
29
|
+
colorInputs.on('change', updateColors);
|
|
30
|
+
updateColors();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function updateColors() {
|
|
34
|
+
$('#preview').css({
|
|
35
|
+
color: $('#color').val(),
|
|
36
|
+
'background-color': $('#bgColor').val(),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function setupUploader() {
|
|
41
|
+
$('#content input[data-action="upload"]').each(function () {
|
|
42
|
+
var uploadBtn = $(this);
|
|
43
|
+
uploadBtn.on('click', function () {
|
|
44
|
+
uploader.show({
|
|
45
|
+
route: config.relative_path + '/api/admin/upload/file',
|
|
46
|
+
params: {
|
|
47
|
+
folder: 'quickstart',
|
|
48
|
+
},
|
|
49
|
+
accept: 'image/*',
|
|
50
|
+
}, function (image) {
|
|
51
|
+
$('#' + uploadBtn.attr('data-target')).val(image);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file shows how client-side javascript can be included via a plugin.
|
|
5
|
+
* If you check `plugin.json`, you'll see that this file is listed under "scripts".
|
|
6
|
+
* That array tells NodeBB which files to bundle into the minified javascript
|
|
7
|
+
* that is served to the end user.
|
|
8
|
+
*
|
|
9
|
+
* There are two (standard) ways to wait for when NodeBB is ready.
|
|
10
|
+
* This one below executes when NodeBB reports it is ready...
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
(async () => {
|
|
14
|
+
const hooks = await app.require('hooks');
|
|
15
|
+
|
|
16
|
+
hooks.on('action:app.load', () => {
|
|
17
|
+
// called once when nbb has loaded
|
|
18
|
+
console.log('hello fab!');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
hooks.on('action:ajaxify.end', (/* data */) => {
|
|
22
|
+
// called everytime user navigates between pages including first load
|
|
23
|
+
});
|
|
24
|
+
})();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* ... and this one reports when the DOM is loaded (but NodeBB might not be fully ready yet).
|
|
28
|
+
* For most cases, you'll want the one above.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
$(document).ready(function () {
|
|
32
|
+
// ...
|
|
33
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
This file is located in the "modules" block of plugin.json
|
|
5
|
+
It is only loaded when the user navigates to /quickstart page
|
|
6
|
+
It is not bundled into the min file that is served on the first load of the page.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
define('forum/quickstart', function () {
|
|
10
|
+
var module = {};
|
|
11
|
+
module.init = function () {
|
|
12
|
+
$('#last-p').text('quickstart.js loaded!');
|
|
13
|
+
};
|
|
14
|
+
return module;
|
|
15
|
+
});
|
package/renovate.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/* Place any SASS in here */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<form>
|
|
2
|
+
<div class="mb-3">
|
|
3
|
+
<label class="form-label" for="name">Name</label>
|
|
4
|
+
<input type="text" id="name" name="name" class="form-control" placeholder="Name" />
|
|
5
|
+
</div>
|
|
6
|
+
<div class="mb-3">
|
|
7
|
+
<label class="form-label" for="description">Description</label>
|
|
8
|
+
<input type="text" id="description" name="description" class="form-control" placeholder="Description" />
|
|
9
|
+
</div>
|
|
10
|
+
</form>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<li data-type="item" class="list-group-item">
|
|
2
|
+
<div class="d-flex gap-2 justify-content-between align-items-start">
|
|
3
|
+
<div class="flex-grow-1">
|
|
4
|
+
<strong>{name}</strong><br />
|
|
5
|
+
<small>{description}</small>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="d-flex gap-1 flex-nowrap">
|
|
8
|
+
<button type="button" data-type="edit" class="btn btn-sm btn-info">Edit</button>
|
|
9
|
+
<button type="button" data-type="remove" class="btn btn-sm btn-danger">Delete</button>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</li>
|