@jhits/plugin-blog 0.0.12 → 0.0.14
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.
- package/package.json +18 -11
- package/README.md +0 -216
package/package.json
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jhits/plugin-blog",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Professional blog management system for the JHITS ecosystem",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"main": "./
|
|
9
|
-
"types": "./
|
|
8
|
+
"main": "./src/index.ts",
|
|
9
|
+
"types": "./src/index.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"types": "./
|
|
13
|
-
"
|
|
12
|
+
"types": "./src/index.tsx",
|
|
13
|
+
"import": "./src/index.tsx",
|
|
14
|
+
"default": "./src/index.tsx"
|
|
15
|
+
},
|
|
16
|
+
"./src": {
|
|
17
|
+
"types": "./src/index.tsx",
|
|
18
|
+
"import": "./src/index.tsx",
|
|
19
|
+
"default": "./src/index.tsx"
|
|
14
20
|
},
|
|
15
21
|
"./server": {
|
|
16
|
-
"types": "./
|
|
17
|
-
"
|
|
22
|
+
"types": "./src/index.server.ts",
|
|
23
|
+
"import": "./src/index.server.ts",
|
|
24
|
+
"default": "./src/index.server.ts"
|
|
18
25
|
}
|
|
19
26
|
},
|
|
20
27
|
"dependencies": {
|
|
@@ -23,9 +30,9 @@
|
|
|
23
30
|
"lucide-react": "^0.564.0",
|
|
24
31
|
"mongodb": "^7.1.0",
|
|
25
32
|
"next-auth": "^4.24.13",
|
|
26
|
-
"@jhits/plugin-content": "0.0.
|
|
27
|
-
"@jhits/plugin-
|
|
28
|
-
"@jhits/plugin-
|
|
33
|
+
"@jhits/plugin-content": "0.0.12",
|
|
34
|
+
"@jhits/plugin-core": "0.0.7",
|
|
35
|
+
"@jhits/plugin-images": "0.0.10"
|
|
29
36
|
},
|
|
30
37
|
"peerDependencies": {
|
|
31
38
|
"next": ">=15.0.0",
|
|
@@ -43,7 +50,7 @@
|
|
|
43
50
|
"eslint": "^10.0.0",
|
|
44
51
|
"eslint-config-next": "16.1.6",
|
|
45
52
|
"next": "16.1.6",
|
|
46
|
-
"next-intl": "4.8.
|
|
53
|
+
"next-intl": "4.8.3",
|
|
47
54
|
"next-themes": "0.4.6",
|
|
48
55
|
"react": "19.2.4",
|
|
49
56
|
"react-dom": "19.2.4",
|
package/README.md
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
# Blog Plugin - Block-Based Architecture
|
|
2
|
-
|
|
3
|
-
A modern, modular Blog Plugin system with a Block-Based Architecture (similar to Notion or Gutenberg) where posts are stored as JSON arrays of "Blocks" rather than HTML blobs.
|
|
4
|
-
|
|
5
|
-
## 🏗️ Architecture Overview
|
|
6
|
-
|
|
7
|
-
### Core Principles
|
|
8
|
-
|
|
9
|
-
1. **Block-Based Storage**: Posts are stored as structured JSON arrays of blocks
|
|
10
|
-
2. **Headless Ready**: All data is saved as structured JSON, perfect for headless CMS usage
|
|
11
|
-
3. **Extensible Registry**: Register new block types without refactoring core
|
|
12
|
-
4. **Separation of Concerns**: Library components are decoupled from editor shell
|
|
13
|
-
5. **Migration-Friendly**: Easy to convert legacy HTML/data to block format
|
|
14
|
-
|
|
15
|
-
## 📁 Directory Structure
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
src/
|
|
19
|
-
├── types/ # TypeScript definitions
|
|
20
|
-
├── registry/ # Block Registry system
|
|
21
|
-
├── state/ # State management (Context + Reducer)
|
|
22
|
-
├── lib/ # Library components (decoupled)
|
|
23
|
-
│ ├── blocks/ # Block rendering
|
|
24
|
-
│ ├── utils/ # Utilities (slugify, etc.)
|
|
25
|
-
│ └── migration/ # Legacy data mapper
|
|
26
|
-
├── views/ # Editor views (to be implemented)
|
|
27
|
-
├── components/ # Shared UI components (to be implemented)
|
|
28
|
-
└── hooks/ # Custom hooks (to be implemented)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed structure.
|
|
32
|
-
|
|
33
|
-
## 🧩 Block System
|
|
34
|
-
|
|
35
|
-
### Default Block Types
|
|
36
|
-
|
|
37
|
-
- **Heading** (`heading`) - H1-H6 headings
|
|
38
|
-
- **Paragraph** (`paragraph`) - Text paragraphs
|
|
39
|
-
- **Image** (`image`) - Single images with captions
|
|
40
|
-
- **Gallery** (`gallery`) - Image galleries
|
|
41
|
-
- **CTA** (`cta`) - Call-to-action blocks
|
|
42
|
-
|
|
43
|
-
### Registering New Blocks
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import { blockRegistry } from '@jhits/plugin-blog';
|
|
47
|
-
|
|
48
|
-
blockRegistry.register({
|
|
49
|
-
type: 'custom-block',
|
|
50
|
-
name: 'Custom Block',
|
|
51
|
-
description: 'My custom block',
|
|
52
|
-
defaultData: {
|
|
53
|
-
customField: '',
|
|
54
|
-
},
|
|
55
|
-
category: 'custom',
|
|
56
|
-
});
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## 🔄 State Management
|
|
60
|
-
|
|
61
|
-
The editor uses React Context + Reducer pattern for state management:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
import { useEditor } from '@jhits/plugin-blog';
|
|
65
|
-
|
|
66
|
-
function MyComponent() {
|
|
67
|
-
const { state, helpers } = useEditor();
|
|
68
|
-
|
|
69
|
-
// Access state
|
|
70
|
-
const { blocks, title, slug } = state;
|
|
71
|
-
|
|
72
|
-
// Use helpers
|
|
73
|
-
helpers.addBlock('paragraph');
|
|
74
|
-
helpers.updateBlock(blockId, { text: 'New text' });
|
|
75
|
-
helpers.save();
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### State Structure
|
|
80
|
-
|
|
81
|
-
- `blocks`: Array of Block objects
|
|
82
|
-
- `title`: Post title
|
|
83
|
-
- `slug`: URL slug
|
|
84
|
-
- `seo`: SEO metadata
|
|
85
|
-
- `metadata`: Categories, tags, featured image
|
|
86
|
-
- `status`: Publication status
|
|
87
|
-
- `isDirty`: Has unsaved changes
|
|
88
|
-
- `focusMode`: Editor focus mode
|
|
89
|
-
|
|
90
|
-
## 📦 Library Components
|
|
91
|
-
|
|
92
|
-
### Block Renderer
|
|
93
|
-
|
|
94
|
-
Headless block rendering (decoupled from editor):
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
import { BlocksRenderer } from '@jhits/plugin-blog/lib';
|
|
98
|
-
|
|
99
|
-
<BlocksRenderer blocks={post.blocks} />
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Utilities
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
import { slugify, generateSlugFromTitle, checkSlugCollision } from '@jhits/plugin-blog/lib';
|
|
106
|
-
|
|
107
|
-
const slug = slugify('My Blog Post');
|
|
108
|
-
const uniqueSlug = generateSlugFromTitle('My Post', existingSlugs);
|
|
109
|
-
const { isCollision } = checkSlugCollision(slug, existingSlugs);
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Migration
|
|
113
|
-
|
|
114
|
-
Convert legacy HTML to blocks:
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
import { mapLegacyPostToBlogPost } from '@jhits/plugin-blog/lib/migration';
|
|
118
|
-
|
|
119
|
-
const newPost = mapLegacyPostToBlogPost(legacyPost, {
|
|
120
|
-
defaultStatus: 'draft',
|
|
121
|
-
authorId: 'user-123',
|
|
122
|
-
});
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## 🎯 Core Views (To Be Implemented)
|
|
126
|
-
|
|
127
|
-
1. **Canvas Editor** - Drag-and-drop block editor
|
|
128
|
-
2. **Slug & SEO Manager** - URL and SEO management with collision detection
|
|
129
|
-
3. **Preview Bridge** - Live preview of posts
|
|
130
|
-
4. **Post Manager** - List view with filters and bulk actions
|
|
131
|
-
|
|
132
|
-
## 🚀 Usage
|
|
133
|
-
|
|
134
|
-
### Basic Setup
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
import { EditorProvider } from '@jhits/plugin-blog';
|
|
138
|
-
|
|
139
|
-
function BlogEditor() {
|
|
140
|
-
return (
|
|
141
|
-
<EditorProvider onSave={async (state) => {
|
|
142
|
-
// Save to API
|
|
143
|
-
await fetch('/api/blog/posts', {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
body: JSON.stringify(state),
|
|
146
|
-
});
|
|
147
|
-
}}>
|
|
148
|
-
<CanvasEditor />
|
|
149
|
-
</EditorProvider>
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## 📝 Data Format
|
|
155
|
-
|
|
156
|
-
### Block Structure
|
|
157
|
-
|
|
158
|
-
```json
|
|
159
|
-
{
|
|
160
|
-
"id": "block-123",
|
|
161
|
-
"type": "paragraph",
|
|
162
|
-
"data": {
|
|
163
|
-
"text": "This is a paragraph"
|
|
164
|
-
},
|
|
165
|
-
"meta": {
|
|
166
|
-
"order": 0
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Post Structure
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"id": "post-123",
|
|
176
|
-
"title": "My Blog Post",
|
|
177
|
-
"slug": "my-blog-post",
|
|
178
|
-
"blocks": [...],
|
|
179
|
-
"seo": {
|
|
180
|
-
"title": "SEO Title",
|
|
181
|
-
"description": "Meta description"
|
|
182
|
-
},
|
|
183
|
-
"publication": {
|
|
184
|
-
"status": "published",
|
|
185
|
-
"date": "2024-01-01T00:00:00Z"
|
|
186
|
-
},
|
|
187
|
-
"metadata": {
|
|
188
|
-
"categories": ["tech"],
|
|
189
|
-
"tags": ["react", "typescript"]
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## 🔧 Extensibility
|
|
195
|
-
|
|
196
|
-
The system is designed to be extended:
|
|
197
|
-
|
|
198
|
-
1. **New Block Types**: Register via `blockRegistry.register()`
|
|
199
|
-
2. **Custom Renderers**: Pass to `BlockRenderer` via `customRenderers` prop
|
|
200
|
-
3. **Custom Actions**: Extend reducer with new action types
|
|
201
|
-
4. **Migration Mappers**: Extend mapper for custom legacy formats
|
|
202
|
-
|
|
203
|
-
## 📚 Next Steps
|
|
204
|
-
|
|
205
|
-
1. Implement Canvas Editor with drag-and-drop
|
|
206
|
-
2. Implement Slug & SEO Manager
|
|
207
|
-
3. Implement Preview Bridge
|
|
208
|
-
4. Implement Post Manager
|
|
209
|
-
5. Add API routes for CRUD operations
|
|
210
|
-
6. Add database integration
|
|
211
|
-
|
|
212
|
-
## 📖 Documentation
|
|
213
|
-
|
|
214
|
-
- [ARCHITECTURE.md](./ARCHITECTURE.md) - Detailed architecture documentation
|
|
215
|
-
- [VIEWS.md](./Markdown/VIEWS.md) - Planned views and features
|
|
216
|
-
|