Replace nil context with context.Background() in content.go to prevent database operations from hanging indefinitely. Clean up outdated documentation files and add current project structure analysis.
146 lines
4.2 KiB
Go
146 lines
4.2 KiB
Go
package engine
|
|
|
|
import (
|
|
"context"
|
|
"slices"
|
|
"strings"
|
|
|
|
"golang.org/x/net/html"
|
|
)
|
|
|
|
// addContentAttributes adds data-content-id attribute only
|
|
func (e *ContentEngine) addContentAttributes(node *html.Node, contentID string) {
|
|
// Add data-content-id attribute
|
|
SetAttribute(node, "data-content-id", contentID)
|
|
}
|
|
|
|
// injectContent injects content from database into elements
|
|
func (e *ContentEngine) injectContent(elements []ProcessedElement, siteID string) error {
|
|
for i := range elements {
|
|
elem := &elements[i]
|
|
|
|
// Get content from database by ID - FIXED: Use context.Background() instead of nil
|
|
contentItem, err := e.client.GetContent(context.Background(), siteID, elem.ID)
|
|
if err != nil {
|
|
// Content not found - skip silently (enhancement mode should not fail on missing content)
|
|
continue
|
|
}
|
|
|
|
if contentItem != nil {
|
|
// Inject the content into the element
|
|
elem.Content = contentItem.HTMLContent
|
|
|
|
// Update injector siteID for this operation
|
|
// HACK: I do not like this. Injector refactor?
|
|
e.injector.siteID = siteID
|
|
e.injector.injectHTMLContent(elem.Node, contentItem.HTMLContent)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// extractHTMLContent extracts the inner HTML content from a node
|
|
func (e *ContentEngine) extractHTMLContent(node *html.Node) string {
|
|
var content strings.Builder
|
|
|
|
// Render all child nodes in order to preserve HTML structure
|
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
|
if err := html.Render(&content, child); err == nil {
|
|
// All nodes (text and element) rendered in correct order
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(content.String())
|
|
}
|
|
|
|
// extractOriginalTemplate extracts the outer HTML of the element (including the element itself)
|
|
func (e *ContentEngine) extractOriginalTemplate(node *html.Node) string {
|
|
var buf strings.Builder
|
|
if err := html.Render(&buf, node); err != nil {
|
|
return ""
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// extractCleanTemplate extracts a clean template without data-content-id attributes and with placeholder content. Used for collection template variants.
|
|
func (e *ContentEngine) extractCleanTemplate(node *html.Node) string {
|
|
// Clone the node to avoid modifying the original
|
|
clonedNode := e.cloneNode(node)
|
|
|
|
// Remove all data-content-id attributes and replace content with placeholders
|
|
e.walkNodes(clonedNode, func(n *html.Node) {
|
|
if n.Type == html.ElementNode {
|
|
// Remove data-content-id attribute
|
|
e.removeAttribute(n, "data-content-id")
|
|
|
|
// If this is an .insertr element, replace content with placeholder
|
|
if e.hasClass(n, "insertr") {
|
|
placeholderText := e.getPlaceholderForElement(n.Data)
|
|
// Clear existing children and add placeholder text
|
|
for child := n.FirstChild; child != nil; {
|
|
next := child.NextSibling
|
|
n.RemoveChild(child)
|
|
child = next
|
|
}
|
|
n.AppendChild(&html.Node{
|
|
Type: html.TextNode,
|
|
Data: placeholderText,
|
|
})
|
|
}
|
|
}
|
|
})
|
|
|
|
var buf strings.Builder
|
|
if err := html.Render(&buf, clonedNode); err != nil {
|
|
return ""
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// removeAttribute removes an attribute from an HTML node
|
|
func (e *ContentEngine) removeAttribute(n *html.Node, key string) {
|
|
for i, attr := range n.Attr {
|
|
if attr.Key == key {
|
|
n.Attr = slices.Delete(n.Attr, i, i+1)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// hasClass checks if a node has a specific class
|
|
func (e *ContentEngine) hasClass(n *html.Node, className string) bool {
|
|
for _, attr := range n.Attr {
|
|
if attr.Key == "class" {
|
|
classes := strings.Fields(attr.Val)
|
|
if slices.Contains(classes, className) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// getPlaceholderForElement returns appropriate placeholder text for different element types
|
|
func (e *ContentEngine) getPlaceholderForElement(elementType string) string {
|
|
placeholders := map[string]string{
|
|
"h1": "Heading 1",
|
|
"h2": "Heading 2",
|
|
"h3": "Heading 3",
|
|
"h4": "Heading 4",
|
|
"h5": "Heading 5",
|
|
"h6": "Heading 6",
|
|
"p": "Paragraph text",
|
|
"span": "Text",
|
|
"div": "Content block",
|
|
"button": "Button",
|
|
"a": "Link text",
|
|
"li": "List item",
|
|
"blockquote": "Quote text",
|
|
}
|
|
|
|
if placeholder, exists := placeholders[elementType]; exists {
|
|
return placeholder
|
|
}
|
|
return "Enter content..."
|
|
}
|