blogger_theme 5.0.0 copy "blogger_theme: ^5.0.0" to clipboard
blogger_theme: ^5.0.0 copied to clipboard

A lightweight standalone Dart library to design Blogger themes with Jaspr-like syntax.

example/main.dart

import 'package:blogger_theme/blogger_theme.dart';

void main() {
  final theme = BloggerTheme(
    attributes: {
      // static compiler flags
      'b:responsive': 'true',
      'b:defaultwidgetversion': '2',
      'b:layoutsversion': '3',
      'b:css': 'false', // Disables default Blogger CSS globally
      /// this removes that <script src=".../widgets.js">
      /// for Better do try  replace the closing </body> with
      /// => &lt;!--</body>--&gt;&lt;/body&gt;
      ///  => this will make those scripts as comment
      /// Reference: [JS as Comment] Below
      // 'b:js': 'false', // Disables default widgets.js globally
      //
      'xmlns': 'http://www.w3.org/1999/xhtml',
      'xmlns:b': 'http://www.google.com/2005/gml/b',
      'xmlns:data': 'http://www.google.com/2005/gml/data',
      'xmlns:expr': 'http://www.google.com/2005/gml/expr',
    },
    // Reset attributes to clean XML output for strict AMP validation
    children: [
      BAttr(name: 'xmlns', value: ''),
      BAttr(name: 'xmlns:b', value: ''),
      BAttr(name: 'xmlns:expr', value: ''),
      BAttr(name: 'xmlns:data', value: ''),
      // Conditionally adds amp="amp" (or lightning bolt symbol ⚡) to <html> on mobile requests
      BAttr(cond: 'data:blog.isMobileRequest', name: 'amp', value: 'amp'),

      // Alternatively, you can use the ⚡ symbol:
      // BAttr(cond: 'data:blog.isMobileRequest', name: '⚡', value: '⚡'),

      // BClass(exprName: '"nJs" + (data:blog.isMobileRequest ? " amp" : "")'), // TODO:[Kept to show we can assign class ]
    ],
    head: [
      Meta(attributes: {"expr:charset": "data:blog.encoding"}),
      Script(
        attributes: {
          'async': 'async',
          'src': 'https://cdn.ampproject.org/v0.js',
        },
      ),
      Meta(
        attributes: {
          "name": "viewport",
          "content": "width=device-width,minimum-scale=1,initial-scale=1",
        },
      ),

      Link(
        attributes: {"rel": "canonical", "expr:href": "data:blog.canonicalUrl"},
      ),
      Link(
        attributes: {
          "rel": "amphtml",
          "expr:href": 'data:blog.canonicalUrl params { m: "1" }',
        },
      ),

      Title(children: [Text('Generated Blogger Theme')]),

      // RawText(
      //   '<style amp-boilerplate="amp-boilerplate">body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>'
      //   '<noscript><style amp-boilerplate="amp-boilerplate">body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>',
      // ),
      // OR For Better Tooling Support [In Future]
      Style(
        attributes: {"amp-boilerplate": "amp-boilerplate"},
        children: [
          Text(
            'body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}',
            escape: false,
          ),
        ],
      ),
      Noscript(
        children: [
          Style(
            attributes: {"amp-boilerplate": "amp-boilerplate"},
            children: [
              Text(
                'body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}',
                escape: false,
              ),
            ],
          ),
        ],
      ),

      // For AMP compliance, keep the CSS string empty ("") and use Style with `amp-custom` attribute and there put your css (limit 50KB)
      BIf(
        cond: false.toString(),
        children: [
          BSkin(
            "",
            variables: [
              //               Text('''

              // /*

              // <!-- Variable definitions -->

              // <Variable name="keycolor" description="Main Color" type="color" default="#8abc0d" value="#ee582e"/>

              // */
              //               '''),
              BVariable(
                name: "keycolor", // Variable identifier used in CSS
                description: "Main Color", // Title shown in Blogger Designer
                type: "color", // Tells Blogger to render a color picker
                defaultValue: "#8abc0d", // Default color
                value: "#ee582e",
              ),
              // TODO: Add variables and Group here
              // Disable default b:skin CSS output while preserving custom Blogger theme variables.
              // Keep the CSS string empty ("") for strict AMP validation.
            ],
          ),
        ],
      ),
      // Place Use custom styles in a <style amp-custom> tag instead (50 KB limit).
      Style(
        attributes: {
          'amp-custom': 'amp-custom',
          'id': "page-skin-1",
          "type": "text/css",
        },
        children: [
          // as we made skin:vars as vars there in top with
          // Your Custom css styles here, for example:
          Text(
            '''
          :root {
      --keycolor: <data:skin.vars.keycolor/>;
    }
           body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
           }
           h1 {
        color: var(--keycolor);
      }
      ''',
            escape: false, // This is Important as if escaped
            //then <data:skin.vars.keycolor/> will be converted and that will not work as aspected
          ),
        ],
      ),

      // here we have a Issue with amp if
      // your Earnings Tab > is Enabled from Blogger Dashboard,
      // then you need to remove the Adsense from that Earning Tab
      // and trick it to use with other methods. and also make sure you
      // don't click on that `Connect Adsense` button from Blogger Dashboard,z
    ],
    body: [const BlogLayout()],
  );

  var xml = theme.generate();
  // Reference: [JS as Comment]
  xml = xml.replaceLast(
    '</body>',
    // or use => &lt;!--</body>--&gt;&lt;/body&gt;
    '''&lt;textarea id=&#39;template_widgets_js&#39; disabled=&#39;disabled&#39; readonly=&#39;readonly&#39; hidden=&#39;hidden&#39; aria-hidden=&#39;true&#39; class=&#39;notranslate&#39;&gt;
  </body>
  &lt;/textarea&gt;
  &lt;/body&gt;''',
  );
  print(xml);
}

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: [],
        ),
        BSection(
          id: 'main-content',
          className: 'main-content-section',
          maxwidgets: 1,
          showaddelement: true,
          children: [
            H1(
              children: [
                Text('My AMP Blogger Theme having H1 Keycolor in '),
                //<b:eval expr="data:skin.vars.keycolor"/></h1>
                BEval(expr: 'data:skin.vars.keycolor'),
              ],
            ),
          ],
        ),
      ],
    ),
  ];
}

extension StringUtils on String {
  /// Replaces the last occurrence of [from] with [to].
  String replaceLast(Pattern from, String to) {
    final match = from.allMatches(this).lastOrNull;
    if (match == null) return this;
    return replaceRange(match.start, match.end, to);
  }
}
1
likes
160
points
209
downloads

Documentation

Documentation
API reference

Publisher

verified publisherhireflutter.uk

Weekly Downloads

A lightweight standalone Dart library to design Blogger themes with Jaspr-like syntax.

Repository (GitHub)
View/report issues

Topics

#html-generation #web #templates #blogger

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

collection, path, web

More

Packages that depend on blogger_theme