-
Notifications
You must be signed in to change notification settings - Fork 578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pages module #126
Comments
You could add a field I tested it quickly (without any magic), here the snippet:
Maybe you could disable the permalink functionality via
in your controller, then you can implement your own logic (Route/Controller etc.) for the frontend. Alternative you can remove the module name from the url via
Hope that helps :) Greets! |
Thank you @noxify the gists works perfectly! Now, I just need to figure how to make block(s) not flexible (so I don't need to have pages table with 50 columns) and I have everything :)
Thanks again for your help, you are awesome! 👍 |
Using
works as expected! |
Thanks @noxify for providing an example! The only thing I would do differently to avoid overriding the @extends('twill::layouts.form')
@include('admin.pages.' . $item->template) @zipavlin thanks for your kind words! Docs around managing stand-alone and parent/child kind of pages could definitely be improved, so let's use this conversation to start working on it. #54 should help for unique (usually seeded) or template based pages but not regarding manageable parent/child pages. I'd like to integrate this in Twill in the future but right now this means manually integrating a model in your app with the laravel-nestedset package. To install the package: Then add nested set columns to your database table: For Laravel 5.5 and above users: Schema::create('pages', function (Blueprint $table) {
...
$table->nestedSet();
});
// To drop columns
Schema::table('pages', function (Blueprint $table) {
$table->dropNestedSet();
}); For prior Laravel versions: ...
use Kalnoy\Nestedset\NestedSet;
Schema::create('pages', function (Blueprint $table) {
...
NestedSet::columns($table);
});
// To drop columns
Schema::table('pages', function (Blueprint $table) {
NestedSet::dropColumns($table);
}); Your model should use use A17\Twill\Models\Behaviors\HasPosition;
use Kalnoy\Nestedset\NodeTrait;
...
class Page extends Model {
use HasPostion, NodeTrait;
...
public static function saveTreeFromIds($nodesArray)
{
$parentNodes = self::find(array_pluck($nodesArray, 'id'));
if (is_array($nodesArray)) {
$position = 1;
foreach ($nodesArray as $nodeArray) {
$node = $parentNodes->where('id', $nodeArray['id'])->first();
$node->position = $position++;
$node->saveAsRoot();
}
}
$parentNodes = self::find(array_pluck($nodesArray, 'id'));
self::rebuildTree($nodesArray, $parentNodes);
}
public static function rebuildTree($nodesArray, $parentNodes)
{
if (is_array($nodesArray)) {
foreach ($nodesArray as $nodeArray) {
$parent = $parentNodes->where('id', $nodeArray['id'])->first();
if (isset($nodeArray['children']) && is_array($nodeArray['children'])) {
$position = 1;
$nodes = self::find(array_pluck($nodeArray['children'], 'id'));
foreach ($nodeArray['children'] as $child) {
//append the children to their (old/new)parents
$descendant = $nodes->where('id', $child['id'])->first();
$descendant->position = $position++;
$descendant->parent_id = $parent->id;
$descendant->save();
self::rebuildTree($nodeArray['children'], $nodes);
}
}
}
}
}
} From your module's repository, you'll need to override the public function setNewOrder($ids)
{
DB::transaction(function () use ($ids) {
Page::saveTreeFromIds($ids);
}, 3);
} If you expect your users to create a lot of records, you'll want to move this operation into a queued job. Finally, to enable Twill's nested listing UI, you'll need to do the following in your module's controller: protected $indexOptions = [
'reorder' => true,
];
protected function indexData($request)
{
return [
'nested' => true,
'nestedDepth' => 2, // this controls the allowed depth in UI
];
}
protected function transformIndexItems($items)
{
return $items->toTree();
}
protected function indexItemData($item)
{
return ($item->children ? [
'children' => $this->getIndexTableData($item->children),
] : []);
} Let me know if you try this and something goes wrong, I'm happy to help! I'm definitely with you on the fact that this is a very common use case for a CMS and we are very interested in providing a way to create some kind of addons or predefined modules as well in the future. |
@ifox thank you for your extended explanation and sorry for my late reply. I changed the structure now, so I no longer need nesting pages, but I definitely will at some point in some other project, so I will check it at that time. It seems this issue is now solved, so I will close this issue. On the other topic: I saw quite some issues have label 'need docs'. Maybe it would make sense to enable contribution to docs? Or something like 'recipes/guides' in docs? I keep finding new possibilities as I am going trough your code base :) |
Hi @zipavlin, sounds good! Docs are open to contributions, the Like I just mentioned on #46 (comment), a guides section would definitely makes sense, great suggestion! |
Great, thanks! 👍 |
Has anyone used this nested module stuff? Is there a way to get nested slugs? F.e. i have the following items:
And now i want to have the slug /en/item-a/item-b) for the Item B and /en/item-a for the Item A. |
Have you solved this yet? |
Have you solved this yet? |
Some time has passed; not sure if anyone else has any input on how to get the nested slugs to work? |
@layout-lab I recently needed pages (nested models). I solved nested slug problem by splitting url path and traversing upstream from last url slug towards its parents. I also rewrote Twill's slug prefix writing to include parent pages. It still needs some work, but I am happy to share my solution when I will be done (I hope I will remember about it). |
Personally I think this is the killer feature missing in Twill. I know there are workarounds but from my experience it's not perfect (see here: https://spectrum.chat/twill/general/subpage-permalinks~e3c1932b-6a6c-4221-a5a9-70e6b99bf96d). I think there should be native support for multi-level pages and dynamic permalinks built in to Twill. Often clients just want a quick and straightforward way of adding pages in a parent-child hierarchy, and therefore I tend to lean towards WordPress for that. Can we expect to have this feature anytime soon? |
I'm really surprised that Twill doesn't have nested slug support… @ifox Is this planned at all? Is there a proper workaround? |
Hey there, I didn't realize there was so much feedback around this missing. The nested-set package has all the functionality embedded to render the tree of pages as needed on the frontend, since each page generates its own slug. The permalink field and link can also be adjusted to render parent pages slugs as the prefix. It is not the most straightforward without better documentation. Our goal is to remove all this manual setup the documentation is currently having you go through and make the feature more robust and first-party in Twill. All that to say this is all possible and I'd love to share a demo that does it but I don't have that at hand right now, at least not something I could easily share. @pboivin and I can work on this soon, we'll keep this thread updated @mikerockett. |
@ifox – thanks so much, looking forward to it! I'll try a manual implementation for the minute. |
Hi @ifox is this page nesting feature now available? Could you please provide steps to prepare nested pages for frontend? |
First of, thanks for sharing your work, it looks amazing!
I am trying to create a pages module, but I am not sure how to go about it.
Documentation states that 'Pages are unstructured data models most often used for static content, such as an About page [...]', which I understand should not be prefixed with 'pages'. I also don't know how to arrange it in page/subpage/... convention. Do you maybe have any more detailed docs about it?
I will also need pages to have different page templates with different fields. I read #54 and will try to implement it somehow, but I would appreciate if you have any ideas how to do that or where to start?
Also related: is it/or would be possible to implement a sort of addons system. For example a 'pages' addon that would scaffold all of this (tree structure, templates, ...) and leave user to populate template' fields, because it seems like something that a lot of projects requiring CMS would actually need.
Thanks for your help!
The text was updated successfully, but these errors were encountered: