Skip to content

Commit fdc3408

Browse files
imorlandStyleCIBot
andauthored
feat: allow defining links via an extender (#71)
* feat: allow defining links via an extender * Apply fixes from StyleCI * add translator for the title * Apply fixes from StyleCI * improve * Apply fixes from StyleCI * phpstan * Apply fixes from StyleCI * drop php 7.x support * begin cleaning up * Apply fixes from StyleCI * refactor: Improve link handling with flattening and child link processing * refactor: Improve link hierarchy handling in LinkRepository * test: Add comprehensive tests for LinkDefinition, LinkRepository, and LinksOverride * working now * Apply fixes from StyleCI * refactor: Consolidate link flattening methods and remove redundancy * feat: Add README and unit tests for LinkDefinition and LinkRepository * docs: Add comprehensive documentation for LinksOverride feature * Apply fixes from StyleCI * chore: update readme * phpstan * chore: remove dev code * chore: remove link editing when override is active * Apply fixes from StyleCI --------- Co-authored-by: StyleCI Bot <[email protected]>
1 parent 80ee657 commit fdc3408

17 files changed

+994
-75
lines changed

.github/workflows/backend.yml

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ jobs:
88
with:
99
enable_backend_testing: true
1010
enable_phpstan: true
11+
php_versions: '["8.0", "8.1", "8.2", "8.3", "8.4"]'
1112

1213
backend_directory: .

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
composer.lock
33
vendor
44
.phpunit.result.cache
5+
.aider*

README.md

+129-14
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,149 @@
1-
# Links by FriendsOfFlarum
1+
# FoF Links
22

3-
![License](https://img.shields.io/badge/license-MIT-blue.svg) [![Latest Stable Version](https://img.shields.io/packagist/v/fof/links.svg)](https://packagist.org/packages/fof/links)
3+
![License](https://img.shields.io/badge/license-MIT-blue.svg) [![Latest Stable Version](https://img.shields.io/packagist/v/fof/links.svg)](https://packagist.org/packages/fof/links) [![Total Downloads](https://img.shields.io/packagist/dt/fof/links.svg)](https://packagist.org/packages/fof/links)
44

5-
A [Flarum](http://flarum.org) extension. Manage Flarum primary navigation links. Original by @sijad.
5+
A [Flarum](http://flarum.org) extension that allows you to add links to your forum's navigation.
66

7-
![links_front](https://cloud.githubusercontent.com/assets/7693001/14650497/47c7c8a4-0681-11e6-9da3-3e99eb080f75.png)
7+
## Features
88

9-
### Installation
9+
- Add links to your forum's navigation menu
10+
- Support for both internal and external links
11+
- Control link visibility based on user groups
12+
- Guest-only links
13+
- Hierarchical links (dropdown menus)
14+
- Programmatic link definition via PHP
1015

11-
Use [Bazaar](https://discuss.flarum.org/d/5151-flagrow-bazaar-the-extension-marketplace) or install manually with composer:
16+
## Installation
1217

13-
```sh
18+
Install with composer:
19+
20+
```bash
1421
composer require fof/links
1522
```
1623

17-
### Updating
24+
## Updating
1825

19-
```sh
26+
```bash
2027
composer update fof/links
28+
php flarum cache:clear
29+
```
30+
31+
## Usage
32+
33+
### Admin Interface
34+
35+
Links can be managed through the admin interface under the "Links" tab.
36+
37+
### Programmatic Link Definition
38+
39+
This extension provides a way to define links programmatically through PHP code. This can be useful in situations where there are multiple environments (ie dev, staging, production) and you want to define a set of links only once (in code), and not have to re-enter or define them via the admin interface.
40+
41+
#### Basic Usage
42+
43+
```php
44+
use FoF\Links\Extend\LinksOverride;
45+
use FoF\Links\LinkDefinition;
46+
47+
return [
48+
// Other extenders...
49+
50+
(new LinksOverride())
51+
->addLinks([
52+
LinkDefinition::make()
53+
->withId(1)
54+
->withTranslationKey('my-extension.link')
55+
->withUrl('/my-page')
56+
->withIcon('fas fa-link')
57+
->withIsInternal(true)
58+
])
59+
];
60+
```
61+
62+
#### Hierarchical Links
63+
64+
You can create dropdown menus by adding child links:
65+
66+
```php
67+
use FoF\Links\Extend\LinksOverride;
68+
use FoF\Links\LinkDefinition;
69+
70+
$parent = LinkDefinition::make()
71+
->withId(1)
72+
->withTranslationKey('my-extension.parent')
73+
->withUrl('/parent');
74+
75+
$child1 = LinkDefinition::make()
76+
->withId(2)
77+
->withTranslationKey('my-extension.child1')
78+
->withUrl('/child1');
79+
80+
$child2 = LinkDefinition::make()
81+
->withId(3)
82+
->withTranslationKey('my-extension.child2')
83+
->withUrl('/child2');
84+
85+
$parent->addChild($child1);
86+
$parent->addChild($child2);
87+
88+
return [
89+
// Other extenders...
90+
91+
(new LinksOverride())
92+
->addLinks([$parent])
93+
];
2194
```
2295

23-
### TODO List by Sijad
96+
#### Using a Provider Class
97+
98+
For more complex scenarios, you can use a provider class:
99+
100+
```php
101+
use FoF\Links\Extend\LinksOverride;
102+
use FoF\Links\LinkDefinition;
103+
104+
class MyLinksProvider
105+
{
106+
public function __invoke()
107+
{
108+
return [
109+
LinkDefinition::make()
110+
->withId(1)
111+
->withTranslationKey('my-extension.link')
112+
->withUrl('/my-page')
113+
];
114+
}
115+
}
116+
117+
return [
118+
// Other extenders...
119+
120+
(new LinksOverride())
121+
->addLinks(MyLinksProvider::class)
122+
];
123+
```
124+
125+
### LinkDefinition API
126+
127+
The `LinkDefinition` class provides a fluent interface for defining links:
24128

25-
- [ ] Add sub items
26-
- [ ] Add permission
129+
| Method | Description |
130+
|--------|-------------|
131+
| `withId(int $id)` | Set the link ID |
132+
| `withTranslationKey(string $key)` | Set the translation key for the link title |
133+
| `withUrl(string $url)` | Set the link URL |
134+
| `withIcon(string $icon)` | Set the link icon (FontAwesome class) |
135+
| `withIsInternal(bool $isInternal)` | Set whether the link is internal |
136+
| `withIsNewtab(bool $isNewtab)` | Set whether the link should open in a new tab |
137+
| `withUseRelme(bool $useRelme)` | Set whether to use rel="me" attribute |
138+
| `withGuestOnly(bool $guestOnly)` | Set whether the link is only visible to guests |
139+
| `withParentId(?int $parentId)` | Set the parent link ID |
140+
| `withPosition(int $position)` | Set the link position |
141+
| `addChild(LinkDefinition $child)` | Add a child link |
27142

28-
### Links
143+
## Links
29144

30145
- [Packagist](https://packagist.org/packages/fof/links)
31146
- [GitHub](https://github.com/FriendsOfFlarum/links)
32-
- [Sijad's Links](https://github.com/sijad/flarum-ext-links)
147+
- [Discuss](https://discuss.flarum.org/d/18335)
33148

34149
An extension by [FriendsOfFlarum](https://github.com/FriendsOfFlarum).

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
}
2020
],
2121
"require": {
22+
"php": "^8.0",
2223
"flarum/core": "^1.8.6"
2324
},
2425
"authors": [

extend.php

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
->post('/permission', 'permission', Controller\SetPermissionController::class),
3939

4040
(new Extend\ApiSerializer(ForumSerializer::class))
41+
->attributes(Api\ForumAttributes::class)
4142
->hasMany('links', LinkSerializer::class),
4243

4344
(new Extend\Event())
@@ -57,4 +58,7 @@
5758

5859
(new Extend\Policy())
5960
->modelPolicy(Link::class, Access\LinkPolicy::class),
61+
62+
(new Extend\ServiceProvider())
63+
->register(Provider\LinksProvider::class),
6064
];

js/src/admin/components/LinksPage.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import app from 'flarum/admin/app';
33
import ExtensionPage from 'flarum/admin/components/ExtensionPage';
44
import Button from 'flarum/common/components/Button';
55
import icon from 'flarum/common/helpers/icon';
6-
6+
import Placeholder from 'flarum/common/components/Placeholder';
77
import sortable from 'sortablejs';
88

99
import EditLinkModal from './EditLinkModal';
@@ -58,6 +58,22 @@ export default class LinksPage extends ExtensionPage {
5858
<h2 className="ExtensionTitle">{app.translator.trans('fof-links.admin.links.links')}</h2>
5959
</div>
6060
</div>
61+
{app.forum.attribute('links.set') ? this.linksPreset() : this.linksContent()}
62+
</div>
63+
);
64+
}
65+
66+
linksPreset() {
67+
return (
68+
<>
69+
<Placeholder text={app.translator.trans('fof-links.admin.links.preconfigured')} />
70+
</>
71+
);
72+
}
73+
74+
linksContent() {
75+
return (
76+
<>
6177
<div className="container">
6278
{Button.component(
6379
{
@@ -80,7 +96,7 @@ export default class LinksPage extends ExtensionPage {
8096
</div>
8197
</div>
8298
</div>
83-
</div>
99+
</>
84100
);
85101
}
86102

locale/en.yml

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ fof-links:
3636
links:
3737
create_button: => fof-links.ref.create_link
3838
links: => fof-links.ref.links
39+
preconfigured: The links on this forum have been preconfigured and cannot be edited here.
3940

4041
settings:
4142
show_icons_only_on_tablet: Show icons only on tablet screens

src/Api/ForumAttributes.php

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of fof/links.
5+
*
6+
* Copyright (c) FriendsOfFlarum.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FoF\Links\Api;
13+
14+
use Flarum\Api\Serializer\ForumSerializer;
15+
16+
class ForumAttributes
17+
{
18+
public function __invoke(ForumSerializer $serializer, mixed $model, array $attributes): array
19+
{
20+
if ($override = resolve('fof-links.override')) {
21+
$attributes['links.set'] = $override;
22+
}
23+
24+
return $attributes;
25+
}
26+
}

src/Api/Serializer/LinkSerializer.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace FoF\Links\Api\Serializer;
1313

1414
use Flarum\Api\Serializer\AbstractSerializer;
15+
use Tobscure\JsonApi\Relationship;
1516

1617
class LinkSerializer extends AbstractSerializer
1718
{
@@ -46,12 +47,16 @@ protected function getDefaultAttributes($link)
4647
}
4748

4849
/**
49-
* @param \FoF\Links\Link $link
50+
* Define the parent relationship.
5051
*
51-
* @return \Tobscure\JsonApi\Relationship
52+
* This ensures overridden links also include their parent in the API response.
5253
*/
53-
protected function parent($link)
54+
protected function parent($link): ?Relationship
5455
{
55-
return $this->hasOne($link, self::class);
56+
if ($link->parent_id !== null) {
57+
return $this->hasOne($link, self::class);
58+
}
59+
60+
return null;
5661
}
5762
}

src/Concerns/HasLinkAttributes.php

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of fof/links.
5+
*
6+
* Copyright (c) FriendsOfFlarum.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FoF\Links\Concerns;
13+
14+
trait HasLinkAttributes
15+
{
16+
/**
17+
* Returns a centralized definition of link attributes.
18+
*
19+
* @return array
20+
*/
21+
public static function getDefaultAttributes(): array
22+
{
23+
return [
24+
'title' => '',
25+
'url' => '',
26+
'icon' => '',
27+
'is_internal' => false,
28+
'is_newtab' => false,
29+
'use_relme' => false,
30+
'guest_only' => false,
31+
'parent_id' => null,
32+
];
33+
}
34+
}

0 commit comments

Comments
 (0)