├── LICENSE.md ├── Services └── ReferenceService.php ├── composer.json ├── index.js ├── index.php ├── preview.png └── readme.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 visionbites GmbH 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Services/ReferenceService.php: -------------------------------------------------------------------------------- 1 | cache('visionbites.usage-reference'); 12 | $expire = option('visionbites.usage-reference.expire') <= 1 ? 1 : option('visionbites.usage-reference.expire'); 13 | $data = $cache->get($uuid); 14 | 15 | if (!$data) { 16 | 17 | if ($template !== null) { 18 | $cacheTag = 'index.' . $template; 19 | 20 | $possibleReferences = $cache->get($cacheTag); 21 | 22 | if (!$possibleReferences) { 23 | $possibleReferences = kirby()->site()->index(true); 24 | $possibleReferences = $possibleReferences->filterBy('intendedTemplate', $template); 25 | $possibleReferences = $possibleReferences->toArray(); 26 | 27 | $cache->set($cacheTag, $possibleReferences, $expire); 28 | } 29 | } else { 30 | $possibleReferences = $cache->get('index'); 31 | 32 | if (!$possibleReferences) { 33 | $possibleReferences = kirby()->site()->index(true); 34 | 35 | $possibleReferences = $possibleReferences->toArray(); 36 | 37 | $cache->set('index', $possibleReferences, $expire); 38 | } 39 | } 40 | 41 | $usedItems = A::filter( 42 | $possibleReferences, 43 | function ($child, $key) use ($uuid) { 44 | 45 | $content = $child['content']; 46 | $hasMatch = false; 47 | 48 | foreach ($content as $datum) { 49 | // if the content is not pretty printed, the uuid might be masked 50 | $maskedUuid = str_replace('/', '\/', $uuid); 51 | 52 | if (is_null($datum) || trim($datum) === "") continue; 53 | 54 | if (str_contains($datum, $uuid) || str_contains($datum, $maskedUuid)) { 55 | $hasMatch = true; 56 | }; 57 | } 58 | return $hasMatch; 59 | } 60 | ); 61 | 62 | $references = []; 63 | foreach ($usedItems as $item) { 64 | $refPage = site()->findPageOrDraft($item['uri']) ?? site()->draft($item['uri']); 65 | 66 | $references[] = [ 67 | 'title' => $refPage->title()->value ?? '', 68 | 'url' => $refPage->url(), 69 | 'slug' => $refPage->slug(), 70 | 'breadcrumb' => $refPage->panel()->breadcrumb(), 71 | 'uuid' => $refPage->uuid()->toString(), 72 | 'template' => $refPage->intendedTemplate()->name(), 73 | 'status' => $refPage->isDraft() ? 'draft' : ($refPage->isUnlisted() ? 'unlisted': 'listed'), 74 | ]; 75 | } 76 | $data = $references; 77 | 78 | $cache->set($uuid, $data, $expire); 79 | } 80 | 81 | return $data; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "visionbites/usage-reference", 3 | "description": "Show references to a page or file on the objects blueprint.", 4 | "license": "MIT", 5 | "version": "1.2.3", 6 | "type": "kirby-plugin", 7 | "authors": [ 8 | { 9 | "name": "Philip Kuban", 10 | "email": "kuban@visionbites.de" 11 | } 12 | ], 13 | "keywords": [ 14 | "kirby", 15 | "kirby-cms", 16 | "kirby-plugin" 17 | ], 18 | "extra": { 19 | "installer-name": "usage-reference" 20 | }, 21 | "require": { 22 | "getkirby/composer-installer": "^1.1" 23 | }, 24 | "autoload": { 25 | "files": ["index.php"], 26 | "psr-4": { 27 | "Visionbites\\UsageReference\\Services\\": "Services/" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | panel.plugin('visionbites/usage-reference', { 2 | sections: { 3 | usageReference: { 4 | data: function () { 5 | return { 6 | headline: null, 7 | references: Array, 8 | items: Array 9 | } 10 | }, 11 | 12 | created: function () { 13 | this.load().then(response => { 14 | this.headline = response.headline; 15 | this.references = response.references; 16 | let items = []; 17 | 18 | this.references.forEach(reference => { 19 | let back; 20 | switch (reference.status) { 21 | case "listed": 22 | back = "var(--color-positive)"; 23 | break; 24 | case "unlisted": 25 | back = "var(--color-blue)"; 26 | break; 27 | case "draft": 28 | back = "var(--color-negative)"; 29 | break; 30 | default: 31 | back = "var(--color-black)"; 32 | break; 33 | } 34 | 35 | items.push({ 36 | preview: [ 37 | { 38 | image: { 39 | icon: "page", 40 | back: back, 41 | color: "white" 42 | }, 43 | text: reference.title, 44 | link: reference.breadcrumb[reference.breadcrumb.length - 1].link, 45 | } 46 | ], 47 | title: reference.title, 48 | template: reference.template, 49 | breadcrumb: reference.breadcrumb, 50 | }) 51 | }); 52 | 53 | this.items = items; 54 | }); 55 | }, 56 | 57 | template: ` 58 | ` 97 | } 98 | } 99 | }); 100 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'expire' => 15, 9 | 'cache' => true, 10 | ], 11 | 'sections' => [ 12 | 'usageReference' => [ 13 | 'props' => [ 14 | 15 | 'headline' => function ($headline = null) { 16 | return I18n::translate($headline); 17 | }, 18 | 'template' => function ($template = null) { 19 | return $template; 20 | } 21 | ], 22 | 23 | 'computed' => [ 24 | 'references' => function () { 25 | $uuid = $this->model()->uuid()->toString(); 26 | $refService = new ReferenceService(); 27 | return $refService->findReferencesForUuid($uuid, $this->template()); 28 | } 29 | ] 30 | 31 | ] 32 | ] 33 | ]); 34 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visionbites/kirby-usage-reference/fb555ab7703bf2f81ad2f77c3a046df0f0afcdc2/preview.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Kirby usage reference plugin 2 | Infosection to display all references to a page or image in a list. 3 | 4 | ![preview](preview.png) 5 | 6 | ## Install 7 | ### Download Zip file 8 | 9 | Copy plugin folder into `site/plugins` 10 | 11 | ### Git submodule 12 | ``` 13 | git submodule add https://github.com/visionbites/kirby-usage-reference.git site/plugins/usage-reference 14 | ``` 15 | 16 | ### Composer 17 | ``` 18 | composer require visionbites/usage-reference 19 | ``` 20 | 21 | ## Usage 22 | Add a section `usageReference` to your blueprint to show references to the current page. 23 | Add a `template` key to define the type of pages you are looking for. 24 | 25 | 26 | ### Example 27 | Basic setup: 28 | 29 | ```yaml 30 | sections: 31 | references: 32 | headline: References to this page 33 | type: usageReference 34 | template: template-name 35 | ``` 36 | 37 | Setup for files: 38 | 39 | ```yaml 40 | sections: 41 | file_data: 42 | type: fields 43 | fields: 44 | title: 45 | type: text 46 | label: Title 47 | alt: 48 | type: text 49 | label: Alternative title 50 | caption: 51 | type: textarea 52 | label: Image caption 53 | references: 54 | headline: References to this file 55 | type: usageReference 56 | ``` 57 | 58 | ## Options 59 | 60 | there are only two options at the moment: 61 | 62 | | Option | Default | Description | 63 | |----------|---------|------------------------------------------------------------------------------------------| 64 | | `expire` | `15` | the cache will expire after n minutes. Minimum is 1 as a indefinite cache makes no sense | 65 | | `cache` | `true` | if set to false will disable the caching of references | 66 | 67 | 68 | set the options in `config.php`: 69 | 70 | ```php 71 | return [ 72 | 'visionbites.usage-reference' => [ 73 | 'expire' => 15 // in minutes 74 | 'cache' => true 75 | ], 76 | ]; 77 | ``` 78 | 79 | please keep in mind that this might lead to showing out of date data to the editor if there was another reference added. 80 | 81 | ## Usage in plugins, models and other places 82 | 83 | you can use the `ReferenceService` that is provided in other places to access the data that is presented in the panel. 84 | 85 | E.g. if you have events attached to a place that are not children of the place itself you can 86 | have a `events()` method in the `PlacePage` model: 87 | ```php 88 | public function events() 89 | { 90 | $refService = new ReferenceService(); 91 | // pass the uuid of the place and the template that you are looking for 92 | $events = $refService->findReferencesForUuid($this->uuid()->toString(), 'event'); 93 | // depending on what you want to do with the events you can either return them here or 94 | // resolve the pages and return a pages collection 95 | $eventsPages = new Pages(); 96 | foreach ($events as $event) { 97 | $eventPage = $this->kirby()->page($event['uuid']); 98 | $eventsPages->append($eventPage); 99 | } 100 | return $eventsPages; 101 | } 102 | ``` 103 | 104 | 105 | ## todos 106 | - [ ] clear cache for a page on update of a referencing page 107 | - [ ] make it pick up on text links 108 | 109 | ## License 110 | 111 | [MIT](https://opensource.org/licenses/MIT) 112 | 113 | It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia animal abuse, violence or any other form of hate speech. 114 | --------------------------------------------------------------------------------