Documentation
¶
Overview ¶
Package generator provides functionality for generating static HTML blog sites from markdown files.
The generator uses the functional options pattern for configuration. Required parameters are passed as positional arguments, while optional parameters are configured via option functions.
TODO: Add usage examples
The Generator returns all generated content in memory via GeneratedBlog. Callers are responsible for I/O operations such as writing files to disk or serving content via HTTP.
The Generator is safe for concurrent use once created, though Generate operations should not be run concurrently on the same Generator instance.
Example ¶
Example demonstrates basic usage of the generator package.
package main
import (
"context"
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
// Create a generator with posts from testdata directory
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil, config.WithRawOutput())
// Generate the blog
ctx := context.Background()
blog, err := gen.Generate(ctx)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Generated %d post(s)\n", len(blog.Posts))
}
Output: Generated 3 post(s)
Example (RawOutput) ¶
Example_rawOutput demonstrates using raw output mode.
package main
import (
"context"
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
// Raw output mode generates HTML without templates
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil, config.WithRawOutput())
ctx := context.Background()
blog, err := gen.Generate(ctx)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Raw HTML mode enabled")
fmt.Printf("Posts generated: %d\n", len(blog.Posts))
}
Output: Raw HTML mode enabled Posts generated: 3
Index ¶
- type GeneratedBlog
- type Generator
- type TemplateRenderer
- func (tr *TemplateRenderer) RenderIndex(data models.IndexPageData) ([]byte, error)
- func (tr *TemplateRenderer) RenderPost(data models.PostPageData) ([]byte, error)
- func (tr *TemplateRenderer) RenderTag(data models.TagPageData) ([]byte, error)
- func (tr *TemplateRenderer) RenderTagsIndex(data models.TagsIndexPageData) ([]byte, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type GeneratedBlog ¶
type GeneratedBlog struct {
Posts map[string][]byte // Posts maps a slug to raw HTML bytes for each post
Index []byte // Index contains the raw HTML for the blog index page
Tags map[string][]byte // Tags maps each tag name to its tag page HTML
TagsIndex []byte // TagsIndex contains the raw HTML for the tags index page
}
GeneratedBlog contains all the HTML content for a complete static blog site.
It includes individual post pages, the main index page, tag pages, and tags index. All content is stored as raw HTML bytes ready to be written to files or served via HTTP.
Post slugs are derived from markdown filenames. Tag names are extracted from post front matter. For more info see pkg/models/Post.
Raw Output Mode ¶
When the generator is configured with config.WithRawOutput(), the content in GeneratedBlog will contain only the parsed Markdown as HTML without any template wrapping:
- Posts map contains clean HTML fragments for each post
- Tags map will be empty (tag pages are not generated)
- TagsIndex will be empty (tags index is not generated)
- Index field will be empty or contain minimal content
This mode is useful for embedding blog content into existing applications, custom CMSs, or when you need to apply your own templates programmatically.
Example ¶
ExampleGeneratedBlog demonstrates working with a GeneratedBlog.
package main
import (
"context"
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil, config.WithRawOutput())
ctx := context.Background()
blog, err := gen.Generate(ctx)
if err != nil {
fmt.Println("Error:", err)
return
}
// Access posts map and verify structure
fmt.Printf("Total posts: %d\n", len(blog.Posts))
fmt.Printf("Has Posts map: %t\n", blog.Posts != nil)
fmt.Printf("Has Tags map: %t\n", blog.Tags != nil)
}
Output: Total posts: 3 Has Posts map: true Has Tags map: true
func NewEmptyGeneratedBlog ¶ added in v2.0.3
func NewEmptyGeneratedBlog() *GeneratedBlog
type Generator ¶
type Generator struct {
PostsDir fs.FS // The filesystem containing the input posts in markdown
config.RawOutput
config.SiteTitle
ParserConfig parser.Config // The config to use when parsing
// contains filtered or unexported fields
}
Generator produces HTML output based on its input configuration. It reads markdown files from a configured filesystem and renders them as HTML using templates.
A Generator is safe for concurrent use after creation, but Generate operations should not be called concurrently on the same instance.
func New ¶
New creates a new Generator with the specified options. It returns an error if the configuration is invalid or if required resources cannot be initialized.
Options can be provided to customize behavior such as template directories, posts per page, and other generation parameters.
Example ¶
ExampleNew demonstrates creating a new generator.
package main
import (
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
// Create a generator with default configuration
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil)
if gen != nil {
fmt.Println("Generator created")
}
}
Output: Generator created
func (*Generator) DebugConfig ¶ added in v2.0.3
DebugConfig logs the current generator configuration at the debug level.
This method is useful for troubleshooting and verifying configuration settings during development or when diagnosing issues. The output includes all generator configuration details and respects the provided context for structured logging.
The log output will only appear if the logger is configured to show debug level messages.
Example ¶
ExampleGenerator_DebugConfig demonstrates debugging generator configuration.
package main
import (
"context"
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil, config.WithRawOutput())
ctx := context.Background()
gen.DebugConfig(ctx)
fmt.Println("Debug output logged")
}
Output: Debug output logged
func (*Generator) Generate ¶
func (g *Generator) Generate(ctx context.Context) (*GeneratedBlog, error)
Generate reads markdown post files from the configured filesystem and generates a complete static blog site as HTML.
It returns a GeneratedBlog containing all rendered HTML content including individual post pages, tag pages, and the index page. The returned content is in-memory only; callers are responsible for writing to disk or serving via HTTP as needed.
Output Mode Behavior ¶
When RawOutput is disabled (default):
- Posts contain fully templated HTML pages
- Tags map contains rendered tag pages
- Index contains the complete index page with template
When RawOutput is enabled (via config.WithRawOutput()):
- Posts contain only the Markdown-to-HTML conversion without templates
- Tags map will be empty (tag generation is skipped)
- Index will be empty or minimal
- Useful for custom integration scenarios
Generate respects the provided context and will return early with context.Canceled or context.DeadlineExceeded if the context is canceled or times out.
It returns an error if markdown files cannot be read, parsing fails, or template rendering encounters an error.
Example ¶
ExampleGenerator_Generate demonstrates generating a blog.
package main
import (
"context"
"fmt"
"os"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
)
func main() {
fsys := os.DirFS("testdata")
gen := generator.New(fsys, nil, config.WithRawOutput())
ctx := context.Background()
blog, err := gen.Generate(ctx)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Blog generation complete")
fmt.Printf("Total posts: %d\n", len(blog.Posts))
}
Output: Blog generation complete Total posts: 3
type TemplateRenderer ¶ added in v2.0.5
type TemplateRenderer struct {
// contains filtered or unexported fields
}
TemplateRenderer handles template loading and rendering.
func NewTemplateRenderer ¶ added in v2.0.5
func NewTemplateRenderer(templatesFS fs.FS) (*TemplateRenderer, error)
NewTemplateRenderer creates a new template renderer from a filesystem. templatesFS should point to a directory containing layouts/, pages/, and partials/.
func (*TemplateRenderer) RenderIndex ¶ added in v2.0.5
func (tr *TemplateRenderer) RenderIndex(data models.IndexPageData) ([]byte, error)
renderIndex renders the index/homepage.
func (*TemplateRenderer) RenderPost ¶ added in v2.0.5
func (tr *TemplateRenderer) RenderPost(data models.PostPageData) ([]byte, error)
renderPost renders a single post page.
func (*TemplateRenderer) RenderTag ¶ added in v2.0.5
func (tr *TemplateRenderer) RenderTag(data models.TagPageData) ([]byte, error)
renderTag renders a tag page.
func (*TemplateRenderer) RenderTagsIndex ¶ added in v2.0.5
func (tr *TemplateRenderer) RenderTagsIndex(data models.TagsIndexPageData) ([]byte, error)
RenderTagsIndex renders the tags index page.