trek 0.1.21 → 0.1.22

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.npmignore +3 -0
  3. data/Gemfile.lock +76 -74
  4. data/README.md +8 -0
  5. data/app/assets/stylesheets/trek/_colors.css +181 -0
  6. data/app/components/trek/button_component.rb +9 -3
  7. data/app/components/trek/form/actions_component/actions_component.css +6 -0
  8. data/app/components/trek/form/image_field_component/image_field_component.css +1 -1
  9. data/app/components/trek/form/switch_box_component.rb +1 -0
  10. data/app/components/trek/tabs_component/tabs_component.css +1 -0
  11. data/app/controllers/concerns/trek/model.rb +4 -1
  12. data/config/locales/trek.en.yml +2 -0
  13. data/docs/.vitepress/config.mjs +133 -0
  14. data/docs/.vitepress/theme/index.js +17 -0
  15. data/docs/.vitepress/theme/style.css +139 -0
  16. data/docs/customize.md +63 -7
  17. data/docs/getting-started.md +160 -0
  18. data/docs/index.md +39 -0
  19. data/docs/public/logo.svg +1 -0
  20. data/docs/reference/components.md +40 -0
  21. data/docs/reference/concerns/contentable.md +28 -0
  22. data/docs/reference/concerns/formattable.md +24 -0
  23. data/docs/reference/concerns/fragmentable.md +33 -0
  24. data/docs/reference/concerns/keyable.md +18 -0
  25. data/docs/reference/concerns/orderable.md +26 -0
  26. data/docs/reference/concerns/pageable.md +35 -0
  27. data/docs/reference/concerns/pathable.md +28 -0
  28. data/docs/reference/concerns/phonable.md +28 -0
  29. data/docs/reference/concerns/search-engine-optimizable.md +19 -0
  30. data/docs/reference/concerns/searchable.md +22 -0
  31. data/docs/reference/concerns/sectionable.md +24 -0
  32. data/docs/reference/concerns/sluggable.md +21 -0
  33. data/docs/reference/concerns/taggable.md +20 -0
  34. data/docs/reference/concerns/translatable.md +35 -0
  35. data/docs/reference/concerns/versionable.md +27 -0
  36. data/docs/reference/controllers.md +23 -0
  37. data/docs/reference/environment-variables.md +9 -0
  38. data/docs/reference/formatters.md +30 -0
  39. data/docs/reference/forms.md +21 -0
  40. data/docs/reference/generators/admin-user.md +17 -0
  41. data/docs/reference/generators/install.md +42 -0
  42. data/docs/reference/generators/scaffold.md +37 -0
  43. data/docs/reference/generators/taxonomies.md +21 -0
  44. data/docs/reference/icons.md +11 -0
  45. data/docs/reference/index.md +47 -0
  46. data/docs/reference/models/current.md +11 -0
  47. data/docs/reference/models/external-link.md +16 -0
  48. data/docs/reference/models/fragment.md +28 -0
  49. data/docs/reference/models/menu-node.md +30 -0
  50. data/docs/reference/models/page-path.md +19 -0
  51. data/docs/reference/models/page-version.md +30 -0
  52. data/docs/reference/models/page.md +48 -0
  53. data/docs/reference/models/tag.md +41 -0
  54. data/docs/reference/models/user.md +65 -0
  55. data/docs/reference/policies.md +30 -0
  56. data/docs/reference/uploaders.md +19 -0
  57. data/docs/what-is-trek.md +37 -0
  58. data/esbuild.config.js +10 -7
  59. data/lib/trek/version.rb +1 -1
  60. data/netlify.toml +4 -0
  61. data/package.json +10 -5
  62. data/renovate.json +4 -0
  63. data/yarn.lock +2015 -235
  64. metadata +48 -2
@@ -0,0 +1,133 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ // https://vitepress.dev/reference/site-config
4
+ export default defineConfig({
5
+ title: "Trek",
6
+ description: "A modern content management & back-office system for Ruby on Rails",
7
+ lang: 'en-US',
8
+ lastUpdated: true,
9
+ themeConfig: {
10
+ logo: { src: '/logo.svg', width: 24, height: 24 },
11
+
12
+ // https://vitepress.dev/reference/default-theme-config
13
+ nav: [
14
+ { text: 'Home', link: '/' },
15
+ { text: 'Guide', link: '/what-is-trek' },
16
+ { text: 'Reference', link: '/reference/' }
17
+ ],
18
+
19
+ sidebar: {
20
+ '/': [
21
+ {
22
+ text: 'Introduction',
23
+ items: [
24
+ { text: "What's Trek?", link: '/what-is-trek' },
25
+ { text: 'Getting started', link: '/getting-started' }
26
+ ]
27
+ },
28
+ {
29
+ text: 'Guides',
30
+ items: [
31
+ { text: 'How to customize Trek', link: '/customize' }
32
+ ]
33
+ },
34
+ {
35
+ text: 'Reference',
36
+ items: [
37
+ { text: 'Reference manual', link: '/reference/' }
38
+ ]
39
+ }
40
+ ],
41
+
42
+ '/reference/': [
43
+ { text: 'Overview', link: '/reference/' },
44
+ {
45
+ text: 'Generators',
46
+ collapsed: false,
47
+ items: [
48
+ { text: 'Installer', link: '/reference/generators/install' },
49
+ { text: 'Admin user', link: '/reference/generators/admin-user' },
50
+ { text: 'Scaffold', link: '/reference/generators/scaffold' },
51
+ { text: 'Taxonomies', link: '/reference/generators/taxonomies' }
52
+ ]
53
+ },
54
+ {
55
+ text: 'Models',
56
+ collapsed: false,
57
+ items: [
58
+ { text: 'Page', link: '/reference/models/page' },
59
+ { text: 'PageVersion', link: '/reference/models/page-version' },
60
+ { text: 'PagePath', link: '/reference/models/page-path' },
61
+ { text: 'Fragment', link: '/reference/models/fragment' },
62
+ { text: 'MenuNode', link: '/reference/models/menu-node' },
63
+ { text: 'ExternalLink', link: '/reference/models/external-link' },
64
+ { text: 'User', link: '/reference/models/user' },
65
+ { text: 'Tag & taxonomy', link: '/reference/models/tag' },
66
+ { text: 'Current', link: '/reference/models/current' }
67
+ ]
68
+ },
69
+ {
70
+ text: 'Concerns',
71
+ collapsed: false,
72
+ items: [
73
+ { text: 'Translatable', link: '/reference/concerns/translatable' },
74
+ { text: 'Contentable', link: '/reference/concerns/contentable' },
75
+ { text: 'Formattable', link: '/reference/concerns/formattable' },
76
+ { text: 'Fragmentable', link: '/reference/concerns/fragmentable' },
77
+ { text: 'Pageable', link: '/reference/concerns/pageable' },
78
+ { text: 'Sluggable', link: '/reference/concerns/sluggable' },
79
+ { text: 'Pathable', link: '/reference/concerns/pathable' },
80
+ { text: 'SearchEngineOptimizable', link: '/reference/concerns/search-engine-optimizable' },
81
+ { text: 'Versionable', link: '/reference/concerns/versionable' },
82
+ { text: 'Sectionable', link: '/reference/concerns/sectionable' },
83
+ { text: 'Orderable', link: '/reference/concerns/orderable' },
84
+ { text: 'Keyable', link: '/reference/concerns/keyable' },
85
+ { text: 'Searchable', link: '/reference/concerns/searchable' },
86
+ { text: 'Taggable', link: '/reference/concerns/taggable' },
87
+ { text: 'Phonable', link: '/reference/concerns/phonable' }
88
+ ]
89
+ },
90
+ {
91
+ text: 'Back-office',
92
+ collapsed: false,
93
+ items: [
94
+ { text: 'Controllers', link: '/reference/controllers' },
95
+ { text: 'Forms', link: '/reference/forms' },
96
+ { text: 'Formatters', link: '/reference/formatters' },
97
+ { text: 'Policies', link: '/reference/policies' },
98
+ { text: 'Uploaders', link: '/reference/uploaders' }
99
+ ]
100
+ },
101
+ {
102
+ text: 'Front-end',
103
+ collapsed: false,
104
+ items: [
105
+ { text: 'Components', link: '/reference/components' },
106
+ { text: 'Icons', link: '/reference/icons' }
107
+ ]
108
+ },
109
+ {
110
+ text: 'Configuration',
111
+ collapsed: false,
112
+ items: [
113
+ { text: 'Environment variables', link: '/reference/environment-variables' }
114
+ ]
115
+ }
116
+ ]
117
+ },
118
+
119
+ search: {
120
+ provider: 'local'
121
+ },
122
+
123
+ socialLinks: [
124
+ { icon: { svg: "<svg height='800' preserveAspectRatio='xMidYMid' viewBox='-18.5 0 293 293' width='800' xmlns='http://www.w3.org/2000/svg'><path d='m76.7478977 97.4337652-.1626607-.1626607-36.1106776 36.1106775 87.6741226 87.511462 36.110678-35.948017 51.563445-51.563445-36.110678-36.1106775v-.1626607h-103.12689z'/><path d='m127.823361.97596426-127.6886576 73.19731944v146.3946393l127.6886576 73.197319 127.688657-73.197319v-146.3946393zm103.28955 205.60313774-103.28955 59.533819-103.2895511-59.533819v-118.7423187l103.2895511-59.5338198 103.28955 59.5338198z'/></svg>" }, link: 'https://rubygems.org/gems/trek' },
125
+ { icon: 'npm', link: 'https://www.npmjs.com/package/trek' }
126
+ ],
127
+
128
+ footer: {
129
+ message: 'Released under the MIT License.',
130
+ copyright: 'Copyright © Etamin Studio'
131
+ }
132
+ }
133
+ })
@@ -0,0 +1,17 @@
1
+ // https://vitepress.dev/guide/custom-theme
2
+ import { h } from 'vue'
3
+ import DefaultTheme from 'vitepress/theme'
4
+ import './style.css'
5
+
6
+ /** @type {import('vitepress').Theme} */
7
+ export default {
8
+ extends: DefaultTheme,
9
+ Layout: () => {
10
+ return h(DefaultTheme.Layout, null, {
11
+ // https://vitepress.dev/guide/extending-default-theme#layout-slots
12
+ })
13
+ },
14
+ enhanceApp({ app, router, siteData }) {
15
+ // ...
16
+ }
17
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Customize default theme styling by overriding CSS variables:
3
+ * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
4
+ */
5
+
6
+ /**
7
+ * Colors
8
+ *
9
+ * Each colors have exact same color scale system with 3 levels of solid
10
+ * colors with different brightness, and 1 soft color.
11
+ *
12
+ * - `XXX-1`: The most solid color used mainly for colored text. It must
13
+ * satisfy the contrast ratio against when used on top of `XXX-soft`.
14
+ *
15
+ * - `XXX-2`: The color used mainly for hover state of the button.
16
+ *
17
+ * - `XXX-3`: The color for solid background, such as bg color of the button.
18
+ * It must satisfy the contrast ratio with pure white (#ffffff) text on
19
+ * top of it.
20
+ *
21
+ * - `XXX-soft`: The color used for subtle background such as custom container
22
+ * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
23
+ * on top of it.
24
+ *
25
+ * The soft color must be semi transparent alpha channel. This is crucial
26
+ * because it allows adding multiple "soft" colors on top of each other
27
+ * to create a accent, such as when having inline code block inside
28
+ * custom containers.
29
+ *
30
+ * - `default`: The color used purely for subtle indication without any
31
+ * special meanings attched to it such as bg color for menu hover state.
32
+ *
33
+ * - `brand`: Used for primary brand colors, such as link text, button with
34
+ * brand theme, etc.
35
+ *
36
+ * - `tip`: Used to indicate useful information. The default theme uses the
37
+ * brand color for this by default.
38
+ *
39
+ * - `warning`: Used to indicate warning to the users. Used in custom
40
+ * container, badges, etc.
41
+ *
42
+ * - `danger`: Used to show error, or dangerous message to the users. Used
43
+ * in custom container, badges, etc.
44
+ * -------------------------------------------------------------------------- */
45
+
46
+ :root {
47
+ --vp-c-default-1: var(--vp-c-gray-1);
48
+ --vp-c-default-2: var(--vp-c-gray-2);
49
+ --vp-c-default-3: var(--vp-c-gray-3);
50
+ --vp-c-default-soft: var(--vp-c-gray-soft);
51
+
52
+ --vp-c-brand-1: var(--vp-c-indigo-1);
53
+ --vp-c-brand-2: var(--vp-c-indigo-2);
54
+ --vp-c-brand-3: var(--vp-c-indigo-3);
55
+ --vp-c-brand-soft: var(--vp-c-indigo-soft);
56
+
57
+ --vp-c-tip-1: var(--vp-c-brand-1);
58
+ --vp-c-tip-2: var(--vp-c-brand-2);
59
+ --vp-c-tip-3: var(--vp-c-brand-3);
60
+ --vp-c-tip-soft: var(--vp-c-brand-soft);
61
+
62
+ --vp-c-warning-1: var(--vp-c-yellow-1);
63
+ --vp-c-warning-2: var(--vp-c-yellow-2);
64
+ --vp-c-warning-3: var(--vp-c-yellow-3);
65
+ --vp-c-warning-soft: var(--vp-c-yellow-soft);
66
+
67
+ --vp-c-danger-1: var(--vp-c-red-1);
68
+ --vp-c-danger-2: var(--vp-c-red-2);
69
+ --vp-c-danger-3: var(--vp-c-red-3);
70
+ --vp-c-danger-soft: var(--vp-c-red-soft);
71
+ }
72
+
73
+ /**
74
+ * Component: Button
75
+ * -------------------------------------------------------------------------- */
76
+
77
+ :root {
78
+ --vp-button-brand-border: transparent;
79
+ --vp-button-brand-text: var(--vp-c-white);
80
+ --vp-button-brand-bg: var(--vp-c-brand-3);
81
+ --vp-button-brand-hover-border: transparent;
82
+ --vp-button-brand-hover-text: var(--vp-c-white);
83
+ --vp-button-brand-hover-bg: var(--vp-c-brand-2);
84
+ --vp-button-brand-active-border: transparent;
85
+ --vp-button-brand-active-text: var(--vp-c-white);
86
+ --vp-button-brand-active-bg: var(--vp-c-brand-1);
87
+ }
88
+
89
+ /**
90
+ * Component: Home
91
+ * -------------------------------------------------------------------------- */
92
+
93
+ :root {
94
+ --vp-home-hero-name-color: transparent;
95
+ --vp-home-hero-name-background: -webkit-linear-gradient(
96
+ 120deg,
97
+ #bd34fe 30%,
98
+ #41d1ff
99
+ );
100
+
101
+ --vp-home-hero-image-background-image: linear-gradient(
102
+ -45deg,
103
+ #bd34fe 50%,
104
+ #47caff 50%
105
+ );
106
+ --vp-home-hero-image-filter: blur(44px);
107
+ }
108
+
109
+ @media (min-width: 640px) {
110
+ :root {
111
+ --vp-home-hero-image-filter: blur(56px);
112
+ }
113
+ }
114
+
115
+ @media (min-width: 960px) {
116
+ :root {
117
+ --vp-home-hero-image-filter: blur(68px);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Component: Custom Block
123
+ * -------------------------------------------------------------------------- */
124
+
125
+ :root {
126
+ --vp-custom-block-tip-border: transparent;
127
+ --vp-custom-block-tip-text: var(--vp-c-text-1);
128
+ --vp-custom-block-tip-bg: var(--vp-c-brand-soft);
129
+ --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
130
+ }
131
+
132
+ /**
133
+ * Component: Algolia
134
+ * -------------------------------------------------------------------------- */
135
+
136
+ .DocSearch {
137
+ --docsearch-primary-color: var(--vp-c-brand-1) !important;
138
+ }
139
+
data/docs/customize.md CHANGED
@@ -1,15 +1,71 @@
1
- ## How to customize Trek
1
+ # How to customize Trek
2
2
 
3
- ### Admin panel branding
3
+ Trek is designed to get you started fast with useful conventions, then get out of the way: most of the generated code lives in your application, so customizing it is just regular Rails work. Here are the most common entry points.
4
+
5
+ ## Admin panel branding
4
6
 
5
7
  You can pick the title and subtitle used in the admin panel header.
6
8
 
7
9
  ```yml
8
10
  # config/locales/en.yml
9
- admin:
10
- brand:
11
- title: My Awesome Project
12
- subtitle: Back-office
11
+ en:
12
+ admin:
13
+ brand:
14
+ title: My Awesome Project
15
+ subtitle: Back-office
16
+ ```
17
+
18
+ ## Favicon & logo
19
+
20
+ Replace Trek's favicon with your own:
21
+
22
+ - in SVG format at `app/assets/images/favicon.svg`
23
+ - in PNG format (512 × 512 px) at `public/favicon.png`
24
+
25
+ ## Components
26
+
27
+ Trek's UI components accept options where it matters:
28
+
29
+ - **`Trek::Form::ActionsComponent`** — pick an `aspect` and add your own `classnames` to restyle form action bars.
30
+ - **`Trek::DialogComponent`** — set the `title` and the buttons of modal dialogs.
31
+ - **`Trek::Form::ContentEditorComponent`** — toggle the `nodes`, `blocks` and `floating` options to slim down the editor where full rich text isn't needed:
32
+
33
+ ```ruby
34
+ f.content_editor :intro, nodes: false, floating: false
13
35
  ```
14
36
 
15
- Place your custom icon in `app/assets/favicon.svg` to use it in place of Trek's favicon.
37
+ - **`Trek::LayoutComponent`** use the `panel` slot to add your own side panel to admin screens.
38
+
39
+ ## Models
40
+
41
+ The models generated by the installer and the scaffold are plain Active Record models in your `app/models`. Enable the commented-out hooks to opt into Trek features, for instance:
42
+
43
+ ```ruby
44
+ class Book < ApplicationRecord
45
+ include Trek::Formattable
46
+ format_attributes Trek::TypographyFormatter, :title
47
+
48
+ include Trek::Translatable
49
+ translate_attributes :title
50
+
51
+ include RecordImageUploader::Attachment(:image)
52
+ end
53
+ ```
54
+
55
+ See the [concerns reference](/reference/) for the full list.
56
+
57
+ ## Policies
58
+
59
+ Each scaffolded resource gets its own policy in `app/policies/admin`. Adjust the rules and `permitted_attributes` per role — the [policies reference](/reference/policies) shows the generated default.
60
+
61
+ ## Theming
62
+
63
+ Trek's admin supports light, dark and auto themes, selectable per user. The design tokens are based on [Radix colors](https://www.radix-ui.com/colors); override the CSS custom properties in your own stylesheet to adapt the palette.
64
+
65
+ ## Dependencies configuration
66
+
67
+ The installer configures Shrine, Postmark, Sorcery, ActionPolicy, Mobility and friends with sensible defaults — through initializers generated **in your app**. You can edit them at any time:
68
+
69
+ - `config/initializers/shrine.rb` — storage backends, upload limits
70
+ - `config/credentials.yml.enc` — Postmark API token (`EDITOR="code --wait" bin/rails credentials:edit`)
71
+ - `config/i18n-tasks.yml` — locale management rules
@@ -0,0 +1,160 @@
1
+ # Getting started
2
+
3
+ This guide takes you from an empty directory to a working Rails application with a Trek back-office.
4
+
5
+ ## Prerequisites
6
+
7
+ Make sure the following are installed:
8
+
9
+ - Ruby 3.1+
10
+ - Rails 7.0+
11
+ - PostgreSQL 12+
12
+ - Node 20+
13
+ - Yarn 3.x
14
+ - libvips
15
+
16
+ Check your Rails version:
17
+
18
+ ```sh
19
+ rails -v
20
+ ```
21
+
22
+ If it's older than 7.0, run `gem install rails` to upgrade.
23
+
24
+ Check your Yarn version:
25
+
26
+ ```sh
27
+ yarn -v
28
+ ```
29
+
30
+ If it's not a 3.x version, run:
31
+
32
+ ```sh
33
+ corepack enable
34
+ corepack install --global yarn@3
35
+ ```
36
+
37
+ ## Create your Rails project
38
+
39
+ Replace `helloworld` with your own project name:
40
+
41
+ ```sh
42
+ export TREK_PROJECT_NAME=helloworld
43
+ rails new $TREK_PROJECT_NAME -j esbuild -d postgresql \
44
+ --skip-action-mailbox --skip-action-text --skip-action-cable \
45
+ --skip-active-storage --skip-jbuilder --skip-test --skip-system-test
46
+ cd $TREK_PROJECT_NAME
47
+ ```
48
+
49
+ ## Get access to Trek
50
+
51
+ Trek is distributed as a gem and an NPM package from Etamin Studio's GitLab. [Create a deploy token](https://git.etaminstud.io/etaminstudio/trek/-/settings/repository#js-deploy-tokens) associated to the Trek project:
52
+
53
+ - **Name**: your project name (e.g. `helloworld`)
54
+ - **Username**: your project name (e.g. `helloworld`)
55
+ - **Scopes**: `read_repository`, `read_package_registry`
56
+
57
+ Export the generated token (replace `XXXXXXXXXXX`):
58
+
59
+ ```sh
60
+ export TREK_DEPLOY_TOKEN=XXXXXXXXXXX
61
+ ```
62
+
63
+ ## Install the gem
64
+
65
+ Add the deploy token to your project's local Bundler config:
66
+
67
+ ```sh
68
+ bundle config git.etaminstud.io $TREK_PROJECT_NAME:$TREK_DEPLOY_TOKEN
69
+ ```
70
+
71
+ Install the gem and add it to your `Gemfile`:
72
+
73
+ ```sh
74
+ bundle add trek --git https://git.etaminstud.io/etaminstudio/trek.git --branch main
75
+ ```
76
+
77
+ Prepare the NPM package installation:
78
+
79
+ ```sh
80
+ export NPM_AUTH_TOKEN=$TREK_DEPLOY_TOKEN
81
+ ```
82
+
83
+ ## Run the installer
84
+
85
+ ```sh
86
+ rails g trek:install
87
+ ```
88
+
89
+ The installer will:
90
+
91
+ - install all dependencies ([see the full list](/what-is-trek#what-you-get))
92
+ - create the `User` model and include Trek's concerns
93
+ - create the `Page`, `PagePath` and `PageVersion` models and include Trek's concerns
94
+ - create the `Fragment` model and include Trek's concerns
95
+ - create the relevant policies
96
+ - generate and run the relevant migrations
97
+ - set up authentication (Sorcery), authorization (ActionPolicy), uploads (Shrine), emails (Postmark), i18n, linting, CI and more
98
+
99
+ ### Configure Postmark (optional)
100
+
101
+ If you already know your [Postmark](https://postmarkapp.com) credentials, define this ENV variable **before** running the installer so it gets injected into the credentials file automatically:
102
+
103
+ ```sh
104
+ export POSTMARK_API_TOKEN=YOUR_TOKEN
105
+ ```
106
+
107
+ You can also do it manually afterwards:
108
+
109
+ ```sh
110
+ EDITOR="code --wait" bin/rails credentials:edit
111
+ ```
112
+
113
+ ### Configure DeepL (optional)
114
+
115
+ DeepL is used to translate locale files automatically when running the scaffold generator. To enable it, define this ENV variable before running the installer:
116
+
117
+ ```sh
118
+ export DEEPL_AUTH_KEY=YOUR_TOKEN
119
+ ```
120
+
121
+ Without it, translations won't happen automatically and you will have to edit each non-English locale file by hand.
122
+
123
+ ## Create an admin user
124
+
125
+ Set `ADMIN_EMAIL` and `ADMIN_PASSWORD` in your `.env`, then run:
126
+
127
+ ```sh
128
+ rails g trek:admin:user
129
+ ```
130
+
131
+ ## Start the server
132
+
133
+ ```sh
134
+ bin/dev
135
+ ```
136
+
137
+ Open `http://localhost:3000/admin` and sign in with your admin credentials. Welcome to your back-office! 🏔
138
+
139
+ ## Scaffold your first resource
140
+
141
+ Trek's scaffold generator creates everything an admin panel needs for a model:
142
+
143
+ ```sh
144
+ rails g trek:scaffold Book title:string intro:text
145
+ ```
146
+
147
+ This generates, in a single command:
148
+
149
+ - the `Book` model and migration (calling the Rails `model` generator behind the scenes)
150
+ - the `Admin::BooksController` based on `Trek::ResourceController`
151
+ - the index, show, new, edit views and form partial
152
+ - the `Admin::BookPolicy` with role-based permissions
153
+ - the admin routes
154
+ - the locale files (auto-translated via DeepL if configured)
155
+ - a menu entry in the admin dashboard
156
+
157
+ Next steps:
158
+
159
+ - [Customize Trek](/customize) — branding, favicon, components
160
+ - [Reference manual](/reference/) — generators, models, components and more
data/docs/index.md ADDED
@@ -0,0 +1,39 @@
1
+ ---
2
+ # https://vitepress.dev/reference/default-theme-home-page
3
+ layout: home
4
+
5
+ hero:
6
+ name: "Trek"
7
+ text: "Take the easy path"
8
+ tagline: "A modern content management & back-office system for Ruby on Rails"
9
+ image:
10
+ src: /logo.svg
11
+ alt: Trek
12
+ actions:
13
+ - theme: brand
14
+ text: What's Trek?
15
+ link: /what-is-trek
16
+ - theme: alt
17
+ text: Quick start
18
+ link: /getting-started
19
+
20
+ features:
21
+ - icon: 🚀
22
+ title: Ready out of the box
23
+ details: One installer sets up authentication, authorization, file uploads, emails, i18n and a polished admin UI — with sensible conventions you can override later.
24
+ - icon: 📝
25
+ title: Modern content editing
26
+ details: A Tiptap-based rich text editor, hierarchical pages with versioning and SEO-friendly paths, plus reusable content fragments.
27
+ - icon: 🛠
28
+ title: Scaffold-driven development
29
+ details: One command generates the model, admin panel, views, policy, routes and locales for any resource — just like Rails scaffolding, but for your back-office.
30
+ - icon: 🌍
31
+ title: Multilingual by default
32
+ details: Content and admin UI translations powered by Mobility and i18n-tasks, with optional automatic translation via DeepL.
33
+ - icon: 🔐
34
+ title: Roles & policies built in
35
+ details: Sorcery authentication and ActionPolicy authorization with admin, editor, user, reader and guest roles, enforced across every panel.
36
+ - icon: 🧩
37
+ title: Hotwire-native UI
38
+ details: ViewComponents, Stimulus and Turbo under the hood, with light & dark themes, Radix colors and a customizable design system.
39
+ ---
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" x="0" y="0" style="enable-background:new 0 0 512 512" version="1.1" viewBox="0 0 512 512"><path d="M0 0h512v512H0z" style="fill:#6ae5ac"/><path d="M201.9 93.5v91h-91c0 50.2 40.7 91 91 91v52c0 50.2 40.7 91 91 91v-325h-91zM292.9 184.5c0 50.2 40.7 91 91 91v-91h-91z" style="fill:#2d2d2d"/><path d="M292.9 418.5v-91h91c-.1 50.2-40.8 91-91 91z" style="fill:#fff"/></svg>
@@ -0,0 +1,40 @@
1
+ # Components
2
+
3
+ Trek's admin UI is built with [ViewComponent](https://viewcomponent.org), [Stimulus](https://stimulus.hotwired.dev) and [Turbo](https://turbo.hotwired.dev), styled with PostCSS and [Radix colors](https://www.radix-ui.com/colors), with light & dark themes.
4
+
5
+ ## UI components
6
+
7
+ The main building blocks, all in the `Trek::` namespace:
8
+
9
+ | Component | Purpose |
10
+ | --- | --- |
11
+ | `LayoutComponent` | admin layout, with header, menu and panel slots |
12
+ | `HeaderComponent` | top navigation bar |
13
+ | `MenuComponent` | sidebar navigation, with polymorphic slots |
14
+ | `BrandComponent` | logo, title & subtitle area |
15
+ | `DialogComponent` | modal dialogs, with configurable title and buttons |
16
+ | `TabsComponent` | tabbed interfaces |
17
+ | `ButtonComponent` | buttons & button-styled links |
18
+ | `ListComponent` | record lists |
19
+ | `PropertiesComponent` | key-value property display |
20
+ | `PaginationComponent` | Kaminari-backed pagination |
21
+ | `ToasterComponent` / `ToastComponent` | flash notifications |
22
+ | `HeadingComponent` | headings |
23
+ | `GateComponent` | authorization-based visibility gate |
24
+ | `IconComponent` | SVG [icon](/reference/icons) renderer |
25
+
26
+ ## Form components
27
+
28
+ Rendered by the [form builder](/reference/forms) helpers, under `Trek::Form::`:
29
+
30
+ `GroupComponent`, `FieldsetComponent`, `ActionsComponent` (configurable aspect & classnames), `ErrorsComponent`, `TextFieldComponent`, `ImageFieldComponent`, `SoundFieldComponent`, `SwitchBoxComponent`, `CollectionSelectComponent`, `GroupedCollectionSelectComponent`, `LinkSelectComponent` and `ContentEditorComponent`.
31
+
32
+ ## Content editor
33
+
34
+ `Trek::Form::ContentEditorComponent` wraps the [Tiptap](https://tiptap.dev) editor and accepts three options — `nodes`, `blocks` and `floating` (all enabled by default) — to toggle the node toolbar, block formatting and floating menu:
35
+
36
+ ```ruby
37
+ f.content_editor :intro, nodes: false, floating: false
38
+ ```
39
+
40
+ Content is stored as ProseMirror JSON and rendered with [`formatted_content`](/reference/concerns/contentable). Image uploads (Uppy), link insertion and prompts are served by the [panel controllers](/reference/controllers).
@@ -0,0 +1,28 @@
1
+ # Trek::Contentable
2
+
3
+ Utilities for rich text stored as ProseMirror JSON in a `content` column — the format produced by Trek's [content editor](/reference/components#content-editor).
4
+
5
+ ## Methods
6
+
7
+ | Method | Returns |
8
+ | --- | --- |
9
+ | `parsed_content` | the content as a hash (parsing JSON strings if needed) |
10
+ | `formatted_content` | safe HTML, rendered through the [ProseMirror pipeline](/reference/formatters) |
11
+ | `content_text` | plain text extracted from all text nodes |
12
+ | `prosemirror_content?` | whether `content` is a valid ProseMirror document |
13
+
14
+ ## Usage
15
+
16
+ ```ruby
17
+ class Page < ApplicationRecord
18
+ include Trek::Contentable
19
+ end
20
+
21
+ page.formatted_content # => "<p>Hello <strong>world</strong></p>"
22
+ page.content_text # => "Hello world"
23
+ ```
24
+
25
+ ## Requirements
26
+
27
+ - A `content` jsonb column
28
+ - Used by [Page](/reference/models/page), [PageVersion](/reference/models/page-version) and [Fragment](/reference/models/fragment)
@@ -0,0 +1,24 @@
1
+ # Trek::Formattable
2
+
3
+ Applies formatters to attributes before validation — out of the box, [`Trek::TypographyFormatter`](/reference/formatters#typographyformatter) and its French typography rules.
4
+
5
+ ## API
6
+
7
+ ```ruby
8
+ class Page < ApplicationRecord
9
+ include Trek::Formattable
10
+ format_attributes Trek::TypographyFormatter, :title, :description
11
+ end
12
+ ```
13
+
14
+ `format_attributes(formatter_class, *attr_names)` registers the attributes; a `before_validation` callback runs the formatter on each of them.
15
+
16
+ ## Usage
17
+
18
+ ```ruby
19
+ page = Page.new(title: "Un titre: voici...")
20
+ page.valid?
21
+ page.title # => "Un titre : voici…"
22
+ ```
23
+
24
+ Works on plain strings **and** on ProseMirror documents (only `text` nodes are touched; the structure is preserved).