From 30e1097b57e188708f8450b17e0860c4701f755e Mon Sep 17 00:00:00 2001 From: Jamie Hurst Date: Sun, 8 Feb 2026 20:41:28 +0000 Subject: [PATCH] switch out default config names and articles/posts --- Dockerfile | 2 +- Dockerfile.test | 2 +- README.md | 8 +-- internal/app/app.go | 53 ++++++++++--------- internal/app/app_test.go | 36 +++++++++++-- internal/app/controller/apiv1/list.go | 2 +- internal/app/controller/apiv1/stats.go | 4 +- internal/app/controller/apiv1/stats_test.go | 4 +- .../app/controller/web/badrequest_test.go | 2 +- internal/app/controller/web/edit_test.go | 2 +- internal/app/controller/web/index_test.go | 6 +-- internal/app/controller/web/new_test.go | 2 +- internal/app/controller/web/stats.go | 26 ++++----- internal/app/controller/web/stats_test.go | 4 +- internal/app/controller/web/view_test.go | 2 +- journal.go | 4 +- journal_test.go | 2 +- web/templates/stats.html.tmpl | 2 +- 18 files changed, 95 insertions(+), 68 deletions(-) diff --git a/Dockerfile b/Dockerfile index e665387..e856fa5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,13 +18,13 @@ COPY --from=0 /go/src/github.com/jamiefdhurst/journal/web web RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --assume-yes libsqlite3-0 ENV GOPATH "/go" -ENV J_ARTICLES_PER_PAGE "" ENV J_CREATE "" ENV J_DB_PATH "" ENV J_DESCRIPTION "" ENV J_EDIT "" ENV J_GA_CODE "" ENV J_PORT "" +ENV J_POSTS_PER_PAGE "" ENV J_THEME "" ENV J_TITLE "" diff --git a/Dockerfile.test b/Dockerfile.test index 69a5729..5f57dbb 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,13 +1,13 @@ FROM golang:1.22-bookworm LABEL org.opencontainers.image.source=https://github.com/jamiefdhurst/journal -ENV J_ARTICLES_PER_PAGE "" ENV J_CREATE "" ENV J_DB_PATH "" ENV J_DESCRIPTION "" ENV J_EDIT "" ENV J_GA_CODE "" ENV J_PORT "" +ENV J_POSTS_PER_PAGE "" ENV J_THEME "" ENV J_TITLE "" diff --git a/README.md b/README.md index e296dd1..81fc5d1 100644 --- a/README.md +++ b/README.md @@ -53,14 +53,14 @@ any additional environment variables. ### General Configuration -* `J_ARTICLES_PER_PAGE` - Articles to display per page, default `20` -* `J_CREATE` - Set to `0` to disable article creation +* `J_CREATE` - Set to `0` to disable post creation * `J_DB_PATH` - Path to SQLite DB - default is `$GOPATH/data/journal.db` * `J_DESCRIPTION` - Set the HTML description of the Journal -* `J_EDIT` - Set to `0` to disable article modification -* `J_EXCERPT_WORDS` - The length of the article shown as a preview/excerpt in the index, default `50` +* `J_EDIT` - Set to `0` to disable post modification +* `J_EXCERPT_WORDS` - The length of the post shown as a preview/excerpt in the index, default `50` * `J_GA_CODE` - Google Analytics tag value, starts with `UA-`, or ignore to disable Google Analytics * `J_PORT` - Port to expose over HTTP, default is `3000` +* `J_POSTS_PER_PAGE` - Posts to display per page, default `20` * `J_THEME` - Theme to use from within the _web/themes_ folder, defaults to `default` * `J_TITLE` - Set the title of the Journal diff --git a/internal/app/app.go b/internal/app/app.go index acff1d5..a30faef 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -36,7 +36,6 @@ type Container struct { // Configuration can be modified through environment variables type Configuration struct { - ArticlesPerPage int DatabasePath string Description string EnableCreate bool @@ -44,6 +43,7 @@ type Configuration struct { ExcerptWords int GoogleAnalyticsCode string Port string + PostsPerPage int SSLCertificate string SSLKey string StaticPath string @@ -61,20 +61,20 @@ type Configuration struct { // DefaultConfiguration returns the default settings for the app func DefaultConfiguration() Configuration { return Configuration{ - ArticlesPerPage: 20, DatabasePath: os.Getenv("GOPATH") + "/data/journal.db", - Description: "A private journal containing Jamie's innermost thoughts", + Description: "A fantastic journal containing some thoughts, ideas and reflections", EnableCreate: true, EnableEdit: true, ExcerptWords: 50, GoogleAnalyticsCode: "", Port: "3000", + PostsPerPage: 20, SSLCertificate: "", SSLKey: "", StaticPath: "web/static", Theme: "default", ThemePath: "web/themes", - Title: "Jamie's Journal", + Title: "A Fantastic Journal", SessionKey: "", SessionName: "journal-session", CookieDomain: "", @@ -99,9 +99,14 @@ func ApplyEnvConfiguration(config *Configuration) { return dotenvVars[key] } + // J_ARTICLES_PER_PAGE is deprecated, but it's checked first articles, _ := strconv.Atoi(getEnv("J_ARTICLES_PER_PAGE")) if articles > 0 { - config.ArticlesPerPage = articles + config.PostsPerPage = articles + } + posts, _ := strconv.Atoi(getEnv("J_POSTS_PER_PAGE")) + if posts > 0 { + config.PostsPerPage = posts } database := getEnv("J_DB_PATH") if database != "" { @@ -128,8 +133,25 @@ func ApplyEnvConfiguration(config *Configuration) { if port != "" { config.Port = port } + config.SSLCertificate = getEnv("J_SSL_CERT") config.SSLKey = getEnv("J_SSL_KEY") + staticPath := getEnv("J_STATIC_PATH") + if staticPath != "" { + config.StaticPath = staticPath + } + theme := getEnv("J_THEME") + if theme != "" { + config.Theme = theme + } + themePath := getEnv("J_THEME_PATH") + if themePath != "" { + config.ThemePath = themePath + } + title := getEnv("J_TITLE") + if title != "" { + config.Title = title + } sessionKey := getEnv("J_SESSION_KEY") if sessionKey != "" { @@ -151,40 +173,19 @@ func ApplyEnvConfiguration(config *Configuration) { if sessionName != "" { config.SessionName = sessionName } - cookieDomain := getEnv("J_COOKIE_DOMAIN") if cookieDomain != "" { config.CookieDomain = cookieDomain } - cookieMaxAge, _ := strconv.Atoi(getEnv("J_COOKIE_MAX_AGE")) if cookieMaxAge > 0 { config.CookieMaxAge = cookieMaxAge } - cookieHTTPOnly := getEnv("J_COOKIE_HTTPONLY") if cookieHTTPOnly == "0" || cookieHTTPOnly == "false" { config.CookieHTTPOnly = false } - if config.SSLCertificate != "" { config.CookieSecure = true } - - staticPath := getEnv("J_STATIC_PATH") - if staticPath != "" { - config.StaticPath = staticPath - } - theme := getEnv("J_THEME") - if theme != "" { - config.Theme = theme - } - themePath := getEnv("J_THEME_PATH") - if themePath != "" { - config.ThemePath = themePath - } - title := getEnv("J_TITLE") - if title != "" { - config.Title = title - } } diff --git a/internal/app/app_test.go b/internal/app/app_test.go index b0835ac..a9978f2 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -9,12 +9,12 @@ import ( func TestDefaultConfiguration(t *testing.T) { config := DefaultConfiguration() - if config.ArticlesPerPage != 20 { - t.Errorf("Expected ArticlesPerPage 20, got %d", config.ArticlesPerPage) - } if config.Port != "3000" { t.Errorf("Expected Port '3000', got %q", config.Port) } + if config.PostsPerPage != 20 { + t.Errorf("Expected PostsPerPage 20, got %d", config.PostsPerPage) + } if config.SessionName != "journal-session" { t.Errorf("Expected SessionName 'journal-session', got %q", config.SessionName) } @@ -389,8 +389,8 @@ J_COOKIE_MAX_AGE=3600 if config.Description != "A test journal" { t.Errorf("Expected Description 'A test journal' from .env, got %q", config.Description) } - if config.ArticlesPerPage != 15 { - t.Errorf("Expected ArticlesPerPage 15 from .env, got %d", config.ArticlesPerPage) + if config.PostsPerPage != 15 { + t.Errorf("Expected PostsPerPage 15 from .env, got %d", config.PostsPerPage) } if config.CookieMaxAge != 3600 { t.Errorf("Expected CookieMaxAge 3600 from .env, got %d", config.CookieMaxAge) @@ -455,3 +455,29 @@ func TestApplyEnvConfiguration_NoDotEnvFile(t *testing.T) { t.Errorf("Expected default Port '3000', got %q", config.Port) } } + +func TestApplyEnvConfiguration_ArticlesDeprecated(t *testing.T) { + // Save current working directory + originalWd, _ := os.Getwd() + defer os.Chdir(originalWd) + + // Create a temporary directory for testing + tmpDir := t.TempDir() + os.Chdir(tmpDir) + + // Create a .env file + envContent := ` +J_POSTS_PER_PAGE=15 +J_ARTICLES_PER_PAGE=10 +` + if err := os.WriteFile(filepath.Join(tmpDir, ".env"), []byte(envContent), 0644); err != nil { + t.Fatalf("Failed to create .env file: %v", err) + } + + config := DefaultConfiguration() + ApplyEnvConfiguration(&config) + + if config.PostsPerPage != 15 { + t.Errorf("Expected PostsPerPage 15 from .env, got %d", config.PostsPerPage) + } +} diff --git a/internal/app/controller/apiv1/list.go b/internal/app/controller/apiv1/list.go index 7fc450e..30a0f21 100644 --- a/internal/app/controller/apiv1/list.go +++ b/internal/app/controller/apiv1/list.go @@ -23,7 +23,7 @@ type List struct { } func ListData(request *http.Request, js model.Journals) ([]model.Journal, database.PaginationInformation) { - paginationQuery := database.PaginationQuery{Page: 1, ResultsPerPage: js.Container.Configuration.ArticlesPerPage} + paginationQuery := database.PaginationQuery{Page: 1, ResultsPerPage: js.Container.Configuration.PostsPerPage} query := request.URL.Query() if query["page"] != nil { page, err := strconv.Atoi(query["page"][0]) diff --git a/internal/app/controller/apiv1/stats.go b/internal/app/controller/apiv1/stats.go index 07ca5b3..b67fb21 100644 --- a/internal/app/controller/apiv1/stats.go +++ b/internal/app/controller/apiv1/stats.go @@ -34,7 +34,7 @@ type statsConfigJSON struct { Title string `json:"title"` Description string `json:"description"` Theme string `json:"theme"` - ArticlesPerPage int `json:"posts_per_page"` + PostsPerPage int `json:"posts_per_page"` GoogleAnalytics bool `json:"google_analytics"` CreateEnabled bool `json:"create_enabled"` EditEnabled bool `json:"edit_enabled"` @@ -58,7 +58,7 @@ func (c *Stats) Run(response http.ResponseWriter, request *http.Request) { stats.Configuration.Title = container.Configuration.Title stats.Configuration.Description = container.Configuration.Description stats.Configuration.Theme = container.Configuration.Theme - stats.Configuration.ArticlesPerPage = container.Configuration.ArticlesPerPage + stats.Configuration.PostsPerPage = container.Configuration.PostsPerPage stats.Configuration.GoogleAnalytics = container.Configuration.GoogleAnalyticsCode != "" stats.Configuration.CreateEnabled = container.Configuration.EnableCreate stats.Configuration.EditEnabled = container.Configuration.EnableEdit diff --git a/internal/app/controller/apiv1/stats_test.go b/internal/app/controller/apiv1/stats_test.go index 435a6a0..7f5c583 100644 --- a/internal/app/controller/apiv1/stats_test.go +++ b/internal/app/controller/apiv1/stats_test.go @@ -13,7 +13,7 @@ import ( func TestStats_Run(t *testing.T) { db := &database.MockSqlite{} configuration := app.DefaultConfiguration() - configuration.ArticlesPerPage = 25 // Custom setting + configuration.PostsPerPage = 25 // Custom setting configuration.GoogleAnalyticsCode = "UA-123456" // Custom GA code container := &app.Container{Configuration: configuration, Db: db} response := &controller.MockResponse{} @@ -38,7 +38,7 @@ func TestStats_Run(t *testing.T) { t.Errorf("Expected post count to be 2, got response %s", response.Content) } if !strings.Contains(response.Content, "posts_per_page\":25,") { - t.Errorf("Expected articles per page to be 25, got response %s", response.Content) + t.Errorf("Expected posts per page to be 25, got response %s", response.Content) } if !strings.Contains(response.Content, "google_analytics\":true") { t.Error("Expected Google Analytics to be enabled") diff --git a/internal/app/controller/web/badrequest_test.go b/internal/app/controller/web/badrequest_test.go index 7a979de..f71b3ea 100644 --- a/internal/app/controller/web/badrequest_test.go +++ b/internal/app/controller/web/badrequest_test.go @@ -35,7 +35,7 @@ func TestError_Run(t *testing.T) { if response.StatusCode != 404 || !strings.Contains(response.Content, "Page Not Found") { t.Error("Expected 404 error when journal not found") } - if !strings.Contains(response.Content, "Page Not Found - Jamie's Journal") { + if !strings.Contains(response.Content, "Page Not Found - A Fantastic Journal") { t.Error("Expected HTML title to be in place") } diff --git a/internal/app/controller/web/edit_test.go b/internal/app/controller/web/edit_test.go index 43f2ee5..2b85325 100644 --- a/internal/app/controller/web/edit_test.go +++ b/internal/app/controller/web/edit_test.go @@ -73,7 +73,7 @@ func TestEdit_Run(t *testing.T) { if strings.Contains(response.Content, "div class=\"error\"") { t.Error("Expected no error to be shown in form") } - if !strings.Contains(response.Content, "Edit Title - Jamie's Journal") { + if !strings.Contains(response.Content, "Edit Title - A Fantastic Journal") { t.Error("Expected HTML title to be in place") } diff --git a/internal/app/controller/web/index_test.go b/internal/app/controller/web/index_test.go index e9e2888..18a7a97 100644 --- a/internal/app/controller/web/index_test.go +++ b/internal/app/controller/web/index_test.go @@ -25,7 +25,7 @@ func init() { func TestIndex_Run(t *testing.T) { db := &database.MockSqlite{} configuration := app.DefaultConfiguration() - configuration.ArticlesPerPage = 2 + configuration.PostsPerPage = 2 configuration.SessionKey = "12345678901234567890123456789012" container := &app.Container{Configuration: configuration, Db: db} response := controller.NewMockResponse() @@ -42,10 +42,10 @@ func TestIndex_Run(t *testing.T) { if !strings.Contains(response.Content, "Title 2") { t.Error("Expected all journals to be displayed on screen") } - if !strings.Contains(response.Content, "Jamie's Journal") { + if !strings.Contains(response.Content, "A Fantastic Journal") { t.Error("Expected default HTML title to be in place") } - if !strings.Contains(response.Content, "Create New Post - Jamie's Journal") { + if !strings.Contains(response.Content, "Create New Post - A Fantastic Journal") { t.Error("Expected HTML title to be in place") } diff --git a/internal/app/controller/web/stats.go b/internal/app/controller/web/stats.go index 62b356f..2f8d2fe 100644 --- a/internal/app/controller/web/stats.go +++ b/internal/app/controller/web/stats.go @@ -15,18 +15,18 @@ type Stats struct { } type statsTemplateData struct { - Container *app.Container - PostCount int - FirstPostDate string - TitleSet bool - DescriptionSet bool - ThemeSet bool - ArticlesPerPage int - GACodeSet bool - CreateEnabled bool - EditEnabled bool - DailyVisits []model.DailyVisit - MonthlyVisits []model.MonthlyVisit + Container *app.Container + PostCount int + FirstPostDate string + TitleSet bool + DescriptionSet bool + ThemeSet bool + PostsPerPage int + GACodeSet bool + CreateEnabled bool + EditEnabled bool + DailyVisits []model.DailyVisit + MonthlyVisits []model.MonthlyVisit } // Run Stats action @@ -52,7 +52,7 @@ func (c *Stats) Run(response http.ResponseWriter, request *http.Request) { data.TitleSet = container.Configuration.Title != defaultConfig.Title data.DescriptionSet = container.Configuration.Description != defaultConfig.Description data.ThemeSet = container.Configuration.Theme != defaultConfig.Theme - data.ArticlesPerPage = container.Configuration.ArticlesPerPage + data.PostsPerPage = container.Configuration.PostsPerPage data.GACodeSet = container.Configuration.GoogleAnalyticsCode != "" data.CreateEnabled = container.Configuration.EnableCreate data.EditEnabled = container.Configuration.EnableEdit diff --git a/internal/app/controller/web/stats_test.go b/internal/app/controller/web/stats_test.go index f437b8d..e413f80 100644 --- a/internal/app/controller/web/stats_test.go +++ b/internal/app/controller/web/stats_test.go @@ -13,7 +13,7 @@ import ( func TestStats_Run(t *testing.T) { db := &database.MockSqlite{} configuration := app.DefaultConfiguration() - configuration.ArticlesPerPage = 25 + configuration.PostsPerPage = 25 configuration.GoogleAnalyticsCode = "UA-123456" container := &app.Container{Configuration: configuration, Db: db} response := controller.NewMockResponse() @@ -39,7 +39,7 @@ func TestStats_Run(t *testing.T) { } if !strings.Contains(response.Content, "
Posts Per Page
\n
25
") { - t.Error("Expected custom articles per page setting to be displayed") + t.Error("Expected custom posts per page setting to be displayed") } if !strings.Contains(response.Content, "
Google Analytics
\n
Enabled
") { diff --git a/internal/app/controller/web/view_test.go b/internal/app/controller/web/view_test.go index 9596db8..721dd7f 100644 --- a/internal/app/controller/web/view_test.go +++ b/internal/app/controller/web/view_test.go @@ -47,7 +47,7 @@ func TestView_Run(t *testing.T) { if strings.Contains(response.Content, "div class=\"error\"") || !strings.Contains(response.Content, "Content") { t.Error("Expected no error to be shown in page") } - if !strings.Contains(response.Content, "Title - Jamie's Journal") { + if !strings.Contains(response.Content, "Title - A Fantastic Journal") { t.Error("Expected HTML title to be in place") } diff --git a/journal.go b/journal.go index 14872b7..4aa69dd 100644 --- a/journal.go +++ b/journal.go @@ -22,10 +22,10 @@ func config() app.Configuration { app.ApplyEnvConfiguration(&configuration) if !configuration.EnableCreate { - log.Println("Article creating is disabled...") + log.Println("Post creating is disabled...") } if !configuration.EnableEdit { - log.Println("Article editing is disabled...") + log.Println("Post editing is disabled...") } return configuration diff --git a/journal_test.go b/journal_test.go index 1224258..c77e06c 100644 --- a/journal_test.go +++ b/journal_test.go @@ -359,7 +359,7 @@ func TestApiV1Stats(t *testing.T) { now := time.Now() date := now.Format("2006-01-02") month := now.Format("2006-01") - expected := fmt.Sprintf(`{"posts":{"count":3,"first_post_date":"2018-01-01"},"configuration":{"title":"Jamie's Journal","description":"A private journal containing Jamie's innermost thoughts","theme":"default","posts_per_page":20,"google_analytics":false,"create_enabled":true,"edit_enabled":true},"visits":{"daily":[{"date":"%s","api_hits":1,"web_hits":0,"total":1}],"monthly":[{"month":"%s","api_hits":1,"web_hits":0,"total":1}]}}`, date, month) + expected := fmt.Sprintf(`{"posts":{"count":3,"first_post_date":"2018-01-01"},"configuration":{"title":"A Fantastic Journal","description":"A fantastic journal containing some thoughts, ideas and reflections","theme":"default","posts_per_page":20,"google_analytics":false,"create_enabled":true,"edit_enabled":true},"visits":{"daily":[{"date":"%s","api_hits":1,"web_hits":0,"total":1}],"monthly":[{"month":"%s","api_hits":1,"web_hits":0,"total":1}]}}`, date, month) // Use contains to get rid of any extra whitespace that we can discount if !strings.Contains(string(body[:]), expected) { diff --git a/web/templates/stats.html.tmpl b/web/templates/stats.html.tmpl index 679df08..e563447 100644 --- a/web/templates/stats.html.tmpl +++ b/web/templates/stats.html.tmpl @@ -25,7 +25,7 @@
{{.Container.Configuration.Theme}}
Posts Per Page
-
{{.ArticlesPerPage}}
+
{{.PostsPerPage}}
Google Analytics
{{if .GACodeSet}}Enabled{{else}}Disabled{{end}}