diff --git a/resources/views/chapters/show.blade.php b/resources/views/chapters/show.blade.php
index 8a86900fb..a7b90ceef 100644
--- a/resources/views/chapters/show.blade.php
+++ b/resources/views/chapters/show.blade.php
@@ -10,6 +10,8 @@
@endpush
+@include('entities.body-tag-classes', ['entity' => $chapter])
+
@section('body')
diff --git a/resources/views/entities/body-tag-classes.blade.php b/resources/views/entities/body-tag-classes.blade.php
new file mode 100644
index 000000000..2edb3e040
--- /dev/null
+++ b/resources/views/entities/body-tag-classes.blade.php
@@ -0,0 +1 @@
+@push('body-class', e((new \BookStack\Actions\TagClassGenerator($entity->tags->all()))->generateAsString() . ' '))
\ No newline at end of file
diff --git a/resources/views/layouts/base.blade.php b/resources/views/layouts/base.blade.php
index c465c5f7e..9f6e9f89a 100644
--- a/resources/views/layouts/base.blade.php
+++ b/resources/views/layouts/base.blade.php
@@ -1,7 +1,7 @@
+ class="{{ setting()->getForCurrentUser('dark-mode-enabled') ? 'dark-mode ' : '' }}">
{{ isset($pageTitle) ? $pageTitle . ' | ' : '' }}{{ setting('app-name') }}
@@ -31,7 +31,7 @@
@stack('translations')
-
+
@include('layouts.parts.base-body-start')
@include('common.skip-to-content')
diff --git a/resources/views/layouts/tri.blade.php b/resources/views/layouts/tri.blade.php
index 4571f4471..e0f16321f 100644
--- a/resources/views/layouts/tri.blade.php
+++ b/resources/views/layouts/tri.blade.php
@@ -1,6 +1,6 @@
@extends('layouts.base')
-@section('body-class', 'tri-layout')
+@push('body-class', 'tri-layout ')
@section('content-components', 'tri-layout')
@section('content')
diff --git a/resources/views/pages/edit.blade.php b/resources/views/pages/edit.blade.php
index cd9635758..98adc849c 100644
--- a/resources/views/pages/edit.blade.php
+++ b/resources/views/pages/edit.blade.php
@@ -1,6 +1,6 @@
@extends('layouts.base')
-@section('body-class', 'flexbox')
+@push('body-class', 'flexbox ')
@section('content')
diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php
index f1aed730b..45d2e2d7f 100644
--- a/resources/views/pages/show.blade.php
+++ b/resources/views/pages/show.blade.php
@@ -4,6 +4,8 @@
@endpush
+@include('entities.body-tag-classes', ['entity' => $page])
+
@section('body')
diff --git a/resources/views/shelves/show.blade.php b/resources/views/shelves/show.blade.php
index 4d440b635..306d55e54 100644
--- a/resources/views/shelves/show.blade.php
+++ b/resources/views/shelves/show.blade.php
@@ -7,6 +7,8 @@
@endif
@endpush
+@include('entities.body-tag-classes', ['entity' => $shelf])
+
@section('body')
diff --git a/tests/Entity/TagTest.php b/tests/Entity/TagTest.php
index 6d03ed95a..1d2c9124f 100644
--- a/tests/Entity/TagTest.php
+++ b/tests/Entity/TagTest.php
@@ -198,9 +198,28 @@ class TagTest extends TestCase
public function test_tag_index_shows_message_on_no_results()
{
- /** @var Page $page */
$resp = $this->asEditor()->get('/tags?search=testingval');
$resp->assertSee('No items available');
$resp->assertSee('Tags can be assigned via the page editor sidebar');
}
+
+ public function test_tag_classes_visible_on_entities()
+ {
+ $this->asEditor();
+
+ foreach ($this->getEachEntityType() as $entity) {
+ $entity->tags()->create(['name' => 'My Super Tag Name', 'value' => 'An-awesome-value']);
+ $html = $this->withHtml($this->get($entity->getUrl()));
+ $html->assertElementExists('body.tag-name-mysupertagname.tag-value-anawesomevalue.tag-pair-mysupertagname-anawesomevalue');
+ }
+ }
+
+ public function test_tag_classes_are_escaped()
+ {
+ $page = Page::query()->first();
+ $page->tags()->create(['name' => '<>']);
+ $resp = $this->asEditor()->get($page->getUrl());
+ $resp->assertDontSee('tag-name-<>', false);
+ $resp->assertSee('tag-name-<>', false);
+ }
}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 95e58b267..9ffce917e 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -428,4 +428,17 @@ abstract class TestCase extends BaseTestCase
$this->assertDatabaseHas('activities', $detailsToCheck);
}
+
+ /**
+ * @return Entity[]
+ */
+ protected function getEachEntityType(): array
+ {
+ return [
+ 'page' => Page::query()->first(),
+ 'chapter' => Chapter::query()->first(),
+ 'book' => Book::query()->first(),
+ 'bookshelf' => Bookshelf::query()->first(),
+ ];
+ }
}