Skip to content

Commit 998ce79

Browse files
compscidrclaude
andcommitted
Scholar plugin auto-creates page record and shows 404 when disabled
- OnInit ensures a research page exists in the pages table with default title, slug, nav settings. Users can customize these via the admin page editor. - Migrates ScholarID from legacy page field to plugin settings for backward compatibility with existing installs. - When the scholar plugin is disabled, visiting the research page shows a "Page Not Available" 404 instead of an empty content page. - Added HasPageType to registry to distinguish "plugin disabled" from "no plugin for this page type". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8c2afa8 commit 998ce79

3 files changed

Lines changed: 61 additions & 5 deletions

File tree

blog/blog.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,11 @@ func (b *Blog) DynamicPage(c *gin.Context, page *Page) {
486486
default:
487487
// Check if a plugin handles this page type
488488
if reg, exists := c.Get("plugin_registry"); exists {
489-
type pageRenderer interface {
489+
type pluginPageHandler interface {
490490
RenderPluginPage(c *gin.Context, pageType string) (string, gin.H, bool)
491+
HasPageType(pageType string) bool
491492
}
492-
if r, ok := reg.(pageRenderer); ok {
493+
if r, ok := reg.(pluginPageHandler); ok {
493494
tmpl, pluginData, handled := r.RenderPluginPage(c, page.PageType)
494495
if handled {
495496
data := gin.H{
@@ -503,13 +504,26 @@ func (b *Blog) DynamicPage(c *gin.Context, page *Page) {
503504
"settings": b.GetSettings(),
504505
"nav_pages": navPages,
505506
}
506-
// Merge plugin data into template data
507507
for k, v := range pluginData {
508508
data[k] = v
509509
}
510510
b.Render(c, http.StatusOK, tmpl, data)
511511
return
512512
}
513+
// Plugin owns this page type but is disabled — show 404
514+
if r.HasPageType(page.PageType) {
515+
b.Render(c, http.StatusNotFound, "error.html", gin.H{
516+
"error": "Page Not Available",
517+
"description": "This page is currently disabled.",
518+
"version": b.Version,
519+
"title": "Not Available",
520+
"recent": b.GetLatest(),
521+
"admin_page": false,
522+
"settings": b.GetSettings(),
523+
"nav_pages": navPages,
524+
})
525+
return
526+
}
513527
}
514528
}
515529
// Fallback: render as custom content page

plugin/registry.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ func (r *Registry) GetNavItems() []PageDefinition {
237237
return items
238238
}
239239

240+
// HasPageType returns true if any registered plugin (enabled or not) defines the given page type.
241+
func (r *Registry) HasPageType(pageType string) bool {
242+
r.mu.RLock()
243+
defer r.mu.RUnlock()
244+
for _, p := range r.plugins {
245+
for _, page := range p.Pages() {
246+
if page.PageType == pageType {
247+
return true
248+
}
249+
}
250+
}
251+
return false
252+
}
253+
240254
// UpdateSetting saves a single plugin setting.
241255
func (r *Registry) UpdateSetting(pluginName, key, value string) {
242256
r.db.Where("plugin_name = ? AND key = ?", pluginName, key).

plugins/scholar/scholar.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package scholar
55

66
import (
77
"fmt"
8+
"goblog/blog"
89
"log"
910
"sort"
1011
"time"
@@ -42,8 +43,35 @@ func (p *ScholarPlugin) Settings() []gplugin.SettingDefinition {
4243
}
4344

4445
func (p *ScholarPlugin) OnInit(db *gorm.DB) error {
45-
// Scholar library will be initialized lazily on first page render
46-
// since we need the settings to know which cache files to use
46+
// Ensure a research page exists in the pages table.
47+
// The user can customize title, slug, hero, nav order via admin.
48+
var page blog.Page
49+
result := db.Where("page_type = ?", "research").First(&page)
50+
if result.Error != nil {
51+
// No research page exists — create the default
52+
page = blog.Page{
53+
Title: "Research",
54+
Slug: "research",
55+
PageType: "research",
56+
ShowInNav: true,
57+
NavOrder: 20,
58+
Enabled: true,
59+
}
60+
db.Create(&page)
61+
log.Println("Scholar plugin: created research page")
62+
}
63+
64+
// Migrate ScholarID from page record to plugin settings (backward compat)
65+
if page.ScholarID != "" {
66+
var existing gplugin.PluginSetting
67+
if err := db.Where("plugin_name = ? AND key = ?", "scholar", "scholar_id").First(&existing).Error; err != nil || existing.Value == "" {
68+
db.Where("plugin_name = ? AND key = ?", "scholar", "scholar_id").
69+
Assign(gplugin.PluginSetting{Value: page.ScholarID}).
70+
FirstOrCreate(&gplugin.PluginSetting{PluginName: "scholar", Key: "scholar_id", Value: page.ScholarID})
71+
log.Printf("Scholar plugin: migrated scholar_id %s from page to plugin settings", page.ScholarID)
72+
}
73+
}
74+
4775
return nil
4876
}
4977

0 commit comments

Comments
 (0)