strapi-plugin-navigation 3.0.13 β 3.0.15
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/README.md +231 -225
- package/dist/admin/index.js +267 -267
- package/dist/admin/index.mjs +5885 -5796
- package/dist/admin/src/pages/HomePage/components/ControllableCombobox/index.d.ts +1 -1
- package/dist/admin/src/pages/HomePage/components/NavigationHeader/index.d.ts +1 -0
- package/dist/admin/src/pages/SettingsPage/common/index.d.ts +1 -1
- package/dist/server/index.js +33 -33
- package/dist/server/index.mjs +3395 -3110
- package/dist/server/src/config/index.d.ts +0 -1
- package/dist/server/src/config/setup.d.ts +1 -1
- package/dist/server/src/graphql/index.d.ts +1 -1
- package/dist/server/src/index.d.ts +0 -1
- package/dist/server/src/repositories/navigation-item.d.ts +9 -0
- package/dist/server/src/services/common/utils.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,27 +31,27 @@ Strapi Navigation Plugin provides a website navigation / menu builder feature fo
|
|
|
31
31
|
- RFR (ready for handling by Redux First Router)
|
|
32
32
|
|
|
33
33
|
### Table of Contents
|
|
34
|
+
|
|
34
35
|
1. [π Versions](#-versions)
|
|
35
36
|
2. [β¨ Features](#-features)
|
|
36
37
|
3. [β³ Installation](#-installation)
|
|
37
38
|
4. [π Requirements](#-requirements)
|
|
38
39
|
5. [π§ Basic Configuration](#-configuration)
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
- [Settings page](#in-v203-and-newer)
|
|
41
|
+
- [Plugin file](#in-v202-and-older--default-configuration-state-for-v203-and-newer)
|
|
41
42
|
6. [π§ GraphQL Configuration](#-gql-configuration)
|
|
42
|
-
7. [
|
|
43
|
-
8. [
|
|
44
|
-
9. [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
11. [
|
|
49
|
-
12. [
|
|
50
|
-
13. [
|
|
51
|
-
14. [
|
|
52
|
-
15. [
|
|
53
|
-
16. [
|
|
54
|
-
17. [π¨βπ» Community support](#-community-support)
|
|
43
|
+
7. [π€ RBAC](#-rbac)
|
|
44
|
+
8. [π Authorization strategy](#-authorization-strategy)
|
|
45
|
+
9. [πΈοΈ Public API specification](#%EF%B8%8F-public-api-specification)
|
|
46
|
+
- [REST API](#rest-api)
|
|
47
|
+
- [GraphQL API](#graphql-api)
|
|
48
|
+
10. [π Extensions](#-extensions)
|
|
49
|
+
11. [πΏ Model lifecycle hooks](#model-life-cycle-hooks)
|
|
50
|
+
12. [π§Ή REST Cache](#rest-cache)
|
|
51
|
+
13. [π§© Examples](#-examples)
|
|
52
|
+
14. [π¬ FAQ](#-faq)
|
|
53
|
+
15. [π€ Contributing](#-contributing-to-the-plugin)
|
|
54
|
+
16. [π¨βπ» Community support](#-community-support)
|
|
55
55
|
|
|
56
56
|
## π Versions
|
|
57
57
|
|
|
@@ -64,10 +64,10 @@ Strapi Navigation Plugin provides a website navigation / menu builder feature fo
|
|
|
64
64
|
- **Navigation Public API:** Simple and ready for use API endpoint for consuming the navigation structure you've created
|
|
65
65
|
- **Visual builder:** Elegant and easy to use visual builder
|
|
66
66
|
- **Any Content Type relation:** Navigation can by linked to any of your Content Types by default. Simply, you're controlling it and also limiting available content types by configuration props
|
|
67
|
-
- **Different types of navigation items:** Create navigation with items linked to internal types, to external links or wrapper elements to keep structure clean
|
|
67
|
+
- **Different types of navigation items:** Create navigation with items linked to internal types, to external links or wrapper elements to keep structure clean
|
|
68
68
|
- **Multiple navigations:** Create as many Navigation containers as you want, setup them and use in the consumer application
|
|
69
|
-
- **Light / Dark mode compatible:** By design we're supporting Strapi βοΈ Light / π Dark modes
|
|
70
|
-
- **Webhooks integration:** Changes to navigation will trigger 'entry.update' or 'entry.create' webhook events.
|
|
69
|
+
- **Light / Dark mode compatible:** By design we're supporting Strapi βοΈ Light / π Dark modes
|
|
70
|
+
- **Webhooks integration:** Changes to navigation will trigger 'entry.update' or 'entry.create' webhook events.
|
|
71
71
|
- **Customizable:** Possibility to customize the options like: available Content Types, Maximum level for "attach to menu", Additional fields (audience)
|
|
72
72
|
|
|
73
73
|
## β³ Installation
|
|
@@ -132,13 +132,12 @@ On the dedicated page, you will be able to set up all crucial properties which d
|
|
|
132
132
|
<img style="width: 100%; height: auto;" src="https://www.sensinum.com/img/open-source/strapi-plugin-navigation/configuration.png" alt="Plugin configuration" />
|
|
133
133
|
</div>
|
|
134
134
|
|
|
135
|
-
>
|
|
135
|
+
> _Note_
|
|
136
136
|
> The default configuration for your plugin is fetched from `config/plugins.js` or, if the file is not there, directly from the plugin itself. If you would like to customize the default state to which you might revert, please follow the next section.
|
|
137
137
|
|
|
138
138
|
### File
|
|
139
139
|
|
|
140
|
-
Config for this plugin is stored as a part of the `config/plugins.{js|ts}` or `config/<env>/plugins.{js|ts}` file. You can use the following snippet to make sure that the config structure is correct. If you've got already configurations for other plugins stores by this way, you can use the `navigation` along with them.
|
|
141
|
-
|
|
140
|
+
Config for this plugin is stored as a part of the `config/plugins.{js|ts}` or `config/<env>/plugins.{js|ts}` file. You can use the following snippet to make sure that the config structure is correct. If you've got already configurations for other plugins stores by this way, you can use the `navigation` along with them.
|
|
142
141
|
|
|
143
142
|
```ts
|
|
144
143
|
module.exports = ({ env }) => ({
|
|
@@ -162,24 +161,26 @@ Config for this plugin is stored as a part of the `config/plugins.{js|ts}` or `c
|
|
|
162
161
|
```
|
|
163
162
|
|
|
164
163
|
### Properties
|
|
164
|
+
|
|
165
165
|
- `additionalFields` - Additional fields for navigation items. More **[ here ](#additional-fields)**
|
|
166
166
|
- `allowedLevels` - Maximum level for which you're able to mark item as "Menu attached"
|
|
167
167
|
- `contentTypes` - UIDs of related content types
|
|
168
168
|
- `contentTypesNameFields` - Definition of content type title fields like `'api::<collection name>.<content type name>': ['field_name_1', 'field_name_2']`, if not set titles are pulled from fields like `['title', 'subject', 'name']`. **TIP** - Proper content type uid you can find in the URL of Content Manager where you're managing relevant entities like: `admin/content-manager/collectionType/< THE UID HERE >?page=1&pageSize=10&sort=Title:ASC&plugins[i18n][locale]=en`
|
|
169
169
|
- `pathDefaultFields` - The attribute to copy the default path from per content type. Syntax: `'api::<collection name>.<content type name>': ['url_slug', 'path']`
|
|
170
170
|
- `gql` - If you're using GraphQL that's the right place to put all necessary settings. More **[ here ](#gql-configuration)**
|
|
171
|
-
- `i18nEnabled` - should you want to manage multi-locale content via navigation set this value `Enabled`. More **[ here ](#i18n)**
|
|
172
171
|
- `cascadeMenuAttached` - If you don't want "Menu attached" to cascade on child items set this value `Disabled`.
|
|
173
172
|
|
|
174
173
|
### Properties
|
|
175
174
|
|
|
176
175
|
### Additional Fields
|
|
177
|
-
|
|
176
|
+
|
|
177
|
+
It is advised to configure additional fields through the plugin's Settings Page. There you can find the table of custom fields and toggle input for the audience field. When enabled, the audience field can be customized through the content manager. Custom fields can be added, edited, toggled, and removed with the use of the table provided on the Settings Page. When removing custom fields be advised that their values in navigation items will be lost. Disabling the custom fields will not affect the data and can be done with no consequence of loosing information.
|
|
178
178
|
|
|
179
179
|
Creating configuration for additional fields with the `config.(js|ts)` file should be done with caution. Config object contains the `additionalFields` property of type `Array<CustomField | 'audience'>`, where CustomField is of type `{ type: 'string' | 'boolean' | 'media', name: string, label: string, enabled?: boolean }`. When creating custom fields be advised that the `name` property has to be unique. When editing a custom field it is advised not to edit its `name` and `type` properties. After config has been restored the custom fields that are not present in `config.js` file will be deleted and their values in navigation items will be lost.
|
|
180
180
|
|
|
181
181
|
## π§ GQL Configuration
|
|
182
|
-
|
|
182
|
+
|
|
183
|
+
Using navigation with GraphQL requires both plugins to be installed and working. You can find installation guide for GraphQL plugin **[here](https://docs.strapi.io/dev-docs/plugins/graphql#graphql)**. To properly configure GQL to work with navigation you should provide `gql` prop. This should contain union types that will be used to define GQL response format for your data while fetching:
|
|
183
184
|
|
|
184
185
|
> **Important!**
|
|
185
186
|
> If you're using `config/plugins.js` to configure your plugins , please put `navigation` property before `graphql`. Otherwise types are not going to be properly added to GraphQL Schema. That's because of dynamic types which base on plugin configuration which are added on `bootstrap` stage, not `register`. This is not valid if you're using `graphql` plugin without any custom configuration, so most of cases in real.
|
|
@@ -190,7 +191,7 @@ items: [NavigationItem]
|
|
|
190
191
|
related: NavigationRelated
|
|
191
192
|
```
|
|
192
193
|
|
|
193
|
-
This prop should look as follows:
|
|
194
|
+
This prop should look as follows:
|
|
194
195
|
|
|
195
196
|
```ts
|
|
196
197
|
gql: {
|
|
@@ -198,39 +199,42 @@ gql: {
|
|
|
198
199
|
},
|
|
199
200
|
```
|
|
200
201
|
|
|
201
|
-
for example:
|
|
202
|
+
for example:
|
|
202
203
|
|
|
203
204
|
```ts
|
|
204
205
|
gql: {
|
|
205
206
|
navigationItemRelated: ['Page', 'UploadFile'],
|
|
206
207
|
},
|
|
207
208
|
```
|
|
208
|
-
where `Page` and `UploadFile` are your type names for the **Content Types** you're referring by navigation items relations.
|
|
209
|
-
|
|
210
|
-
## π i18n
|
|
211
209
|
|
|
212
|
-
|
|
210
|
+
where `Page` and `UploadFile` are your type names for the **Content Types** you're referring by navigation items relations.
|
|
213
211
|
|
|
214
212
|
## π€ RBAC
|
|
213
|
+
|
|
215
214
|
Plugin provides granular permissions based on **Strapi RBAC** functionality within the editorial interface & **Admin API**. Those settings are editable via the _Setings_ -> _Administration Panel_ -> _Roles_.
|
|
216
215
|
|
|
217
216
|
For any role different than **Super Admin**, to access the **Navigation panel** you must set following permissions:
|
|
218
217
|
|
|
219
218
|
### Mandatory permissions
|
|
219
|
+
|
|
220
220
|
- _Plugins_ -> _Navigation_ -> _Read_ - gives you the access to **Navigation Panel**
|
|
221
221
|
|
|
222
222
|
### Other permissions
|
|
223
|
+
|
|
223
224
|
- _Plugins_ -> _Navigation_ -> _Update_ - with this permission user is able to change Navigation structure
|
|
224
225
|
- _Plugins_ -> _Navigation_ -> _Settings_ - special permission for users that should be able to change plugin settings
|
|
225
226
|
|
|
226
227
|
## π Authorization strategy
|
|
227
|
-
|
|
228
|
+
|
|
229
|
+
Is applied for **Public API** both for REST and GraphQL. You can manage is by two different ways. Those settings are editable via the _Setings_ -> _Users & Permissions Plugin_ -> _Roles_.
|
|
228
230
|
|
|
229
231
|
## User based
|
|
232
|
+
|
|
230
233
|
- _Public_ - as per description it's default role for any not authenticated user. By enabling **Public API** of the plugin here you're making it **fully public**, without **any permissions check**.
|
|
231
234
|
- _Authenticated_ - as per description this is default role for Strapi Users. If you enable **Public API** here, for any call made you must use the User authentication token as `Bearer <token>`.
|
|
232
235
|
|
|
233
236
|
## Token based
|
|
237
|
+
|
|
234
238
|
- _Full Access_ - gives full access to every Strapi Content API including our plugin endpoints as well.
|
|
235
239
|
- _Custom_ - granural access management to every Strapi Content API endpoints as well as plugin **Public API** - _(recomended approach)_
|
|
236
240
|
|
|
@@ -244,66 +248,71 @@ Is applied for **Public API** both for REST and GraphQL. You can manage is by tw
|
|
|
244
248
|
## Base Navigation Item model
|
|
245
249
|
|
|
246
250
|
### Flat
|
|
251
|
+
|
|
247
252
|
```json
|
|
248
253
|
{
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
254
|
+
"id": 1,
|
|
255
|
+
"documentId": "njx99iv4p4txuqp307ye8625",
|
|
256
|
+
"title": "News",
|
|
257
|
+
"type": "INTERNAL",
|
|
258
|
+
"path": "news",
|
|
259
|
+
"externalPath": null,
|
|
260
|
+
"uiRouterKey": "News",
|
|
261
|
+
"menuAttached": false,
|
|
262
|
+
"parent": 8, // Parent Navigation Item 'id', null in case of root level
|
|
263
|
+
"master": 1, // Navigation 'id'
|
|
264
|
+
"createdAt": "2020-09-29T13:29:19.086Z",
|
|
265
|
+
"updatedAt": "2020-09-29T13:29:19.128Z",
|
|
266
|
+
"related": {
|
|
267
|
+
/*<Content Type model >*/
|
|
268
|
+
},
|
|
269
|
+
"audience": []
|
|
263
270
|
}
|
|
264
271
|
```
|
|
265
272
|
|
|
266
273
|
### Tree
|
|
274
|
+
|
|
267
275
|
```json
|
|
268
276
|
{
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
277
|
+
"title": "News",
|
|
278
|
+
"menuAttached": true,
|
|
279
|
+
"path": "/news",
|
|
280
|
+
"type": "INTERNAL",
|
|
281
|
+
"uiRouterKey": "news",
|
|
282
|
+
"slug": "benefits",
|
|
283
|
+
"external": false,
|
|
284
|
+
"related": {
|
|
285
|
+
// <Content Type model >
|
|
286
|
+
},
|
|
287
|
+
"items": [
|
|
288
|
+
{
|
|
289
|
+
"title": "External url",
|
|
290
|
+
"menuAttached": true,
|
|
291
|
+
"path": "http://example.com",
|
|
292
|
+
"type": "EXTERNAL",
|
|
293
|
+
"uiRouterKey": "generic",
|
|
294
|
+
"external": true
|
|
295
|
+
}
|
|
296
|
+
// < Tree Navigation Item models >
|
|
297
|
+
]
|
|
290
298
|
}
|
|
291
299
|
```
|
|
292
300
|
|
|
293
301
|
### RFR
|
|
302
|
+
|
|
294
303
|
```json
|
|
295
304
|
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
305
|
+
"id": "News",
|
|
306
|
+
"title": "News",
|
|
307
|
+
"related": {
|
|
308
|
+
"contentType": "page",
|
|
309
|
+
"collectionName": "pages",
|
|
310
|
+
"id": 1
|
|
311
|
+
},
|
|
312
|
+
"path": "/news",
|
|
313
|
+
"slug": "news",
|
|
314
|
+
"parent": null, // Parent Navigation Item 'id', null in case of root level
|
|
315
|
+
"menuAttached": true
|
|
307
316
|
}
|
|
308
317
|
```
|
|
309
318
|
|
|
@@ -315,13 +324,14 @@ Plugin supports both **REST API** and **GraphQL API** exposed by Strapi.
|
|
|
315
324
|
|
|
316
325
|
- `navigationIdOrSlug` - ID or slug for which your navigation structure is generated like for REST API:
|
|
317
326
|
|
|
318
|
-
> `https://localhost:1337/api/navigation/render/njx99iv4p4txuqp307ye8625`
|
|
319
|
-
> `https://localhost:1337/api/navigation/render/main-menu`
|
|
327
|
+
> `https://localhost:1337/api/navigation/render/njx99iv4p4txuqp307ye8625` > `https://localhost:1337/api/navigation/render/main-menu`
|
|
320
328
|
|
|
321
329
|
- `type` - Enum value representing structure type of returned navigation:
|
|
330
|
+
|
|
322
331
|
> `https://localhost:1337/api/navigation/render/njx99iv4p4txuqp307ye8625?type=FLAT`
|
|
323
332
|
|
|
324
333
|
- `menu` (`menuOnly` for GQL) - Boolean value for querying only navigation items that are attached to menu should be rendered eg.
|
|
334
|
+
|
|
325
335
|
> `https://localhost:1337/api/navigation/render/njx99iv4p4txuqp307ye8625?menu=true`
|
|
326
336
|
|
|
327
337
|
- `path` - String value for querying navigation items by its path:
|
|
@@ -412,28 +422,28 @@ Return a rendered navigation structure depends on passed type (`TREE`, `RFR` or
|
|
|
412
422
|
|
|
413
423
|
```json
|
|
414
424
|
[
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
425
|
+
{
|
|
426
|
+
"id": 1,
|
|
427
|
+
"documentId": "njx99iv4p4txuqp307ye8625",
|
|
428
|
+
"title": "News",
|
|
429
|
+
"type": "INTERNAL",
|
|
430
|
+
"path": "news",
|
|
431
|
+
"externalPath": null,
|
|
432
|
+
"uiRouterKey": "News",
|
|
433
|
+
"menuAttached": false,
|
|
434
|
+
"parent": null,
|
|
435
|
+
"master": 1,
|
|
436
|
+
"created_at": "2020-09-29T13:29:19.086Z",
|
|
437
|
+
"updated_at": "2020-09-29T13:29:19.128Z",
|
|
438
|
+
"related": {
|
|
439
|
+
"__contentType": "Page",
|
|
440
|
+
"id": 1,
|
|
441
|
+
"documentId": "njx99iv4p4txuqp307ye8625",
|
|
442
|
+
"title": "News"
|
|
443
|
+
// ...
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// ...
|
|
437
447
|
]
|
|
438
448
|
```
|
|
439
449
|
|
|
@@ -443,33 +453,33 @@ Return a rendered navigation structure depends on passed type (`TREE`, `RFR` or
|
|
|
443
453
|
|
|
444
454
|
```json
|
|
445
455
|
[
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
},
|
|
460
|
-
"items": [
|
|
461
|
-
{
|
|
462
|
-
"title": "External url",
|
|
463
|
-
"menuAttached": true,
|
|
464
|
-
"path": "http://example.com",
|
|
465
|
-
"type": "EXTERNAL",
|
|
466
|
-
"uiRouterKey": "generic",
|
|
467
|
-
"external": true
|
|
468
|
-
},
|
|
469
|
-
// ...
|
|
470
|
-
]
|
|
456
|
+
{
|
|
457
|
+
"title": "News",
|
|
458
|
+
"menuAttached": true,
|
|
459
|
+
"path": "/news",
|
|
460
|
+
"type": "INTERNAL",
|
|
461
|
+
"uiRouterKey": "news",
|
|
462
|
+
"slug": "benefits",
|
|
463
|
+
"external": false,
|
|
464
|
+
"related": {
|
|
465
|
+
"__contentType": "Page",
|
|
466
|
+
"id": 1,
|
|
467
|
+
"title": "News"
|
|
468
|
+
// ...
|
|
471
469
|
},
|
|
472
|
-
|
|
470
|
+
"items": [
|
|
471
|
+
{
|
|
472
|
+
"title": "External url",
|
|
473
|
+
"menuAttached": true,
|
|
474
|
+
"path": "http://example.com",
|
|
475
|
+
"type": "EXTERNAL",
|
|
476
|
+
"uiRouterKey": "generic",
|
|
477
|
+
"external": true
|
|
478
|
+
}
|
|
479
|
+
// ...
|
|
480
|
+
]
|
|
481
|
+
}
|
|
482
|
+
// ...
|
|
473
483
|
]
|
|
474
484
|
```
|
|
475
485
|
|
|
@@ -479,77 +489,77 @@ Return a rendered navigation structure depends on passed type (`TREE`, `RFR` or
|
|
|
479
489
|
|
|
480
490
|
```json
|
|
481
491
|
{
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
},
|
|
496
|
-
"Community": {
|
|
497
|
-
"id": "Community",
|
|
498
|
-
"title": "Community",
|
|
499
|
-
"related": {
|
|
500
|
-
"contentType": "page",
|
|
501
|
-
"collectionName": "pages",
|
|
502
|
-
"id": 2
|
|
503
|
-
},
|
|
504
|
-
"path": "/community",
|
|
505
|
-
"slug": "community",
|
|
506
|
-
"parent": null,
|
|
507
|
-
"menuAttached": true
|
|
508
|
-
},
|
|
509
|
-
"Highlights": {
|
|
510
|
-
"id": "Highlights",
|
|
511
|
-
"title": "Highlights",
|
|
512
|
-
"related": {
|
|
513
|
-
"contentType": "page",
|
|
514
|
-
"collectionName": "pages",
|
|
515
|
-
"id": 3
|
|
516
|
-
},
|
|
517
|
-
"path": "/community/highlights",
|
|
518
|
-
"slug": "community-highlights",
|
|
519
|
-
"parent": "Community",
|
|
520
|
-
"menuAttached": false
|
|
521
|
-
},
|
|
522
|
-
// ...
|
|
492
|
+
"pages": {
|
|
493
|
+
"News": {
|
|
494
|
+
"id": "News",
|
|
495
|
+
"title": "News",
|
|
496
|
+
"related": {
|
|
497
|
+
"contentType": "page",
|
|
498
|
+
"collectionName": "pages",
|
|
499
|
+
"id": 1
|
|
500
|
+
},
|
|
501
|
+
"path": "/news",
|
|
502
|
+
"slug": "news",
|
|
503
|
+
"parent": null,
|
|
504
|
+
"menuAttached": true
|
|
523
505
|
},
|
|
524
|
-
"
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
"
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
// ...
|
|
550
|
-
],
|
|
551
|
-
// ...
|
|
506
|
+
"Community": {
|
|
507
|
+
"id": "Community",
|
|
508
|
+
"title": "Community",
|
|
509
|
+
"related": {
|
|
510
|
+
"contentType": "page",
|
|
511
|
+
"collectionName": "pages",
|
|
512
|
+
"id": 2
|
|
513
|
+
},
|
|
514
|
+
"path": "/community",
|
|
515
|
+
"slug": "community",
|
|
516
|
+
"parent": null,
|
|
517
|
+
"menuAttached": true
|
|
518
|
+
},
|
|
519
|
+
"Highlights": {
|
|
520
|
+
"id": "Highlights",
|
|
521
|
+
"title": "Highlights",
|
|
522
|
+
"related": {
|
|
523
|
+
"contentType": "page",
|
|
524
|
+
"collectionName": "pages",
|
|
525
|
+
"id": 3
|
|
526
|
+
},
|
|
527
|
+
"path": "/community/highlights",
|
|
528
|
+
"slug": "community-highlights",
|
|
529
|
+
"parent": "Community",
|
|
530
|
+
"menuAttached": false
|
|
552
531
|
}
|
|
532
|
+
// ...
|
|
533
|
+
},
|
|
534
|
+
"nav": {
|
|
535
|
+
"root": [
|
|
536
|
+
{
|
|
537
|
+
"label": "News",
|
|
538
|
+
"type": "internal",
|
|
539
|
+
"page": "News"
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
"label": "Community",
|
|
543
|
+
"type": "internal",
|
|
544
|
+
"page": "Community"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"label": "External url",
|
|
548
|
+
"type": "external",
|
|
549
|
+
"url": "http://example.com"
|
|
550
|
+
}
|
|
551
|
+
// ...
|
|
552
|
+
],
|
|
553
|
+
"Community": [
|
|
554
|
+
{
|
|
555
|
+
"label": "Highlights",
|
|
556
|
+
"type": "internal",
|
|
557
|
+
"page": "Highlights"
|
|
558
|
+
}
|
|
559
|
+
// ...
|
|
560
|
+
]
|
|
561
|
+
// ...
|
|
562
|
+
}
|
|
553
563
|
}
|
|
554
564
|
```
|
|
555
565
|
|
|
@@ -561,11 +571,7 @@ Same as [**REST API**](#rest-api) returns a rendered navigation structure depend
|
|
|
561
571
|
|
|
562
572
|
```graphql
|
|
563
573
|
query {
|
|
564
|
-
renderNavigation(
|
|
565
|
-
navigationIdOrSlug: "main-navigation"
|
|
566
|
-
type: TREE
|
|
567
|
-
menuOnly: false
|
|
568
|
-
) {
|
|
574
|
+
renderNavigation(navigationIdOrSlug: "main-navigation", type: TREE, menuOnly: false) {
|
|
569
575
|
id
|
|
570
576
|
title
|
|
571
577
|
path
|
|
@@ -659,10 +665,10 @@ For example:
|
|
|
659
665
|
module.exports = {
|
|
660
666
|
// ...
|
|
661
667
|
bootstrap({ strapi }) {
|
|
662
|
-
const navigationCommonService = strapi.plugin(
|
|
668
|
+
const navigationCommonService = strapi.plugin('navigation').service('common');
|
|
663
669
|
const originalGetSlug = navigationCommonService.getSlug;
|
|
664
670
|
const preprocess = (q) => {
|
|
665
|
-
return q +
|
|
671
|
+
return q + 'suffix';
|
|
666
672
|
};
|
|
667
673
|
|
|
668
674
|
navigationCommonService.getSlug = (query) => {
|
|
@@ -682,34 +688,32 @@ Lifecycle hooks can be register either in `register()` or `bootstrap()` methods
|
|
|
682
688
|
|
|
683
689
|
Listeners can by sync and `async`.
|
|
684
690
|
|
|
685
|
-
>Be aware that lifecycle hooks registered in `register()` may be fired by plugin's bootstrapping. If you want listen to events triggered after server's startup use `bootstrap()`.
|
|
691
|
+
> Be aware that lifecycle hooks registered in `register()` may be fired by plugin's bootstrapping. If you want listen to events triggered after server's startup use `bootstrap()`.
|
|
686
692
|
|
|
687
693
|
Example:
|
|
688
694
|
|
|
689
695
|
```ts
|
|
690
|
-
|
|
691
|
-
.plugin("navigation")
|
|
692
|
-
.service("common");
|
|
696
|
+
const navigationCommonService = strapi.plugin('navigation').service('common');
|
|
693
697
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
698
|
+
navigationCommonService.registerLifecycleHook({
|
|
699
|
+
callback: async ({ action, result }) => {
|
|
700
|
+
const saveResult = await logIntoSystem(action, result);
|
|
697
701
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
702
|
+
console.log(saveResult);
|
|
703
|
+
},
|
|
704
|
+
contentTypeName: 'navigation',
|
|
705
|
+
hookName: 'afterCreate',
|
|
706
|
+
});
|
|
703
707
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
708
|
+
navigationCommonService.registerLifecycleHook({
|
|
709
|
+
callback: async ({ action, result }) => {
|
|
710
|
+
const saveResult = await logIntoSystem(action, result);
|
|
707
711
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
712
|
+
console.log(saveResult);
|
|
713
|
+
},
|
|
714
|
+
contentTypeName: 'navigation-item',
|
|
715
|
+
hookName: 'afterCreate',
|
|
716
|
+
});
|
|
713
717
|
```
|
|
714
718
|
|
|
715
719
|
## π§Ή REST Cache
|
|
@@ -738,8 +742,8 @@ Live example of plugin usage can be found in the [VirtusLab Strapi Examples](htt
|
|
|
738
742
|
|
|
739
743
|
```ts
|
|
740
744
|
module.exports = {
|
|
741
|
-
|
|
742
|
-
|
|
745
|
+
navigation: { enabled: true },
|
|
746
|
+
graphql: { enabled: true },
|
|
743
747
|
};
|
|
744
748
|
```
|
|
745
749
|
|
|
@@ -781,9 +785,11 @@ Feel free to fork and make a Pull Request to this plugin project. All the input
|
|
|
781
785
|
4. Run your Strapi instance
|
|
782
786
|
|
|
783
787
|
### :octocat: Core team
|
|
788
|
+
|
|
784
789
|
[@CodeVoyager](https://github.com/CodeVoyager) [@cyp3rius](https://github.com/cyp3rius)
|
|
785
790
|
|
|
786
791
|
### π Strapi Community
|
|
792
|
+
|
|
787
793
|
[@jorrit](https://github.com/jorrit)
|
|
788
794
|
|
|
789
795
|
## π¨βπ» Community support
|