If you have ever tried building or customizing a Blogger (Blogspot) theme from scratch, you know the struggle. Managing massive, unstructured XML files and mixing standard HTML with Blogger's proprietary tags quickly devolves into a frustrating maintenance nightmare.
Enter blogger_theme—a robust Dart package designed to bring structure, strict type safety, and a modern component-based architecture to Blogger theme development.
1. Why Choose blogger_theme?
- Component-Based Architecture: Break your complex layouts down into modular, reusable components, bringing the clean developer experience (DX) of modern frameworks like Flutter or React straight to Blogger.
- Type-Safe Blogger Tags: Catch missing attributes and structural syntax errors at compile-time rather than upload-time. Use native Dart classes for elements like
BSection,BWidget,BIf, andBData. - Built-in Client Scripting: Seamlessly compile and embed local Dart client scripts directly into inline JavaScript to handle frontend interactivity effortlessly.
2. Getting Started & Core Example
This snippet demonstrates how to set up a layout framework, apply responsive theme attributes, inject global CSS, and isolate specific post views using conditional rendering.
import 'dart:io';
import 'package:blogger_theme/blogger_theme.dart';
class BlogLayout extends Component {
const BlogLayout();
@override
Iterable<Component> build() => [
Div(
attributes: {'class': 'wrapper-pane'},
children: [
BSection(
id: 'header-area',
className: 'header-section',
maxwidgets: 1,
showaddelement: true,
children: [
BWidget(
id: 'Header1',
type: 'Header',
title: 'Blog Header Title',
locked: true,
),
],
),
// Renders content exclusively on individual post pages
BIf(
cond: 'data:view.isPost',
children: [
Div(
attributes: {'class': 'post-item'},
children: [BData(value: 'post.body')],
),
],
),
],
),
];
}
void main() {
final theme = BloggerTheme(
attributes: {
'b:responsive': 'true',
'b:defaultwidgetversion': '2',
'b:layoutsversion': '3',
},
head: [
Title(children: [Text('Generated Blogger Theme')]),
BSkin('body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }'),
],
body: [
const BlogLayout(),
],
);
final xml = theme.generate();
final outputFile = File('build/blogger_theme.xml');
outputFile.createSync(recursive: true);
outputFile.writeAsStringSync(xml);
print('Success! Wrote generated theme to ${outputFile.path}');
}
3. Under the Hood
BSection&BWidget: Map directly to native<b:section>and<b:widget>elements, establishing structured drop-zones for the Blogger Layout Editor.BIf(Conditional Rendering): Emulates native<b:if cond="...">tags. It targetsdata:view.isPostto ensure post body markup is delivered only on article pages.BloggerTheme.generate(): The engine core that parses your declarative Dart tree, injects standard boilerplate XML schemas, and formats valid XML ready for upload.
4. Advanced: Handling Loops
Displaying indexes, main feeds, and comment threads requires looping through data streams. Implement these cleanly by embedding loop structures inside your layout tree:
// Example layout fragment for a post feed loop
BLoop(
values: 'data:posts',
varName: 'post',
children: [
Article(
attributes: {'class': 'feed-summary'},
children: [
H2(children: [BData(value: 'post.title')]),
Span(children: [BData(value: 'post.date')]),
],
),
],
)
By shifting your theme infrastructure to blogger_theme, you modernize your pipeline, leverage Dart's static analysis to prevent broken templates, and keep your codebase organized.
Ready to transform your workflow? Explore the full documentation, check out the API details, and install the package today via pub.dev/packages/blogger_theme.
