someTag function

Parser<Tag> someTag(
  1. String name, {
  2. LiquidConfig? config,
  3. Parser? start,
  4. Parser? end,
  5. Parser? content,
  6. Parser? filters,
  7. bool hasContent = true,
})

Creates a tag parser for a named tag with optional custom delimiters.

This is the primary way to create custom tags. Use the config parameter to specify custom delimiters, or leave it null for standard Liquid delimiters.

Parameters

  • name: The tag name to match (e.g., 'mytag' matches {% mytag %})
  • config: Optional delimiter configuration. If null, uses standard delimiters.
  • start: Optional custom start delimiter parser (overrides config)
  • end: Optional custom end delimiter parser (overrides config)
  • content: Optional custom content parser
  • filters: Optional custom filters parser
  • hasContent: Whether the tag has content between delimiters (default: true)

Example with Custom Delimiters

final config = LiquidConfig(tagStart: '[%', tagEnd: '%]');

// Register a custom tag with custom delimiters
TagRegistry.register('greeting', (content, filters) {
  return GreetingTag(content, filters);
}, parser: () => someTag('greeting', config: config));

// Now parses: [% greeting "Hello" %]

Example with Standard Delimiters

// Register a custom tag with standard delimiters
TagRegistry.register('mytag', (content, filters) {
  return MyTag(content, filters);
}, parser: () => someTag('mytag'));

// Now parses: {% mytag %}

Example: Tag Without Content

final breakTag = someTag('break', hasContent: false);
// Matches: {% break %}

See also:

Implementation

Parser<Tag> someTag(
  String name, {
  LiquidConfig? config,
  Parser<dynamic>? start,
  Parser<dynamic>? end,
  Parser<dynamic>? content,
  Parser<dynamic>? filters,
  bool hasContent = true,
}) {
  // Use provided parsers, or create from config, or use defaults
  final startParser = start ?? createTagStart(config);
  final endParser = end ?? createTagEnd(config);

  var parser = (startParser & string(name).trim());

  if (hasContent) {
    parser =
        parser &
        (content ?? ref0(tagContent).optional()).trim() &
        (filters ?? ref0(filter).star()).trim();
  }

  parser = parser & endParser;

  return parser
      .map((values) {
        if (!hasContent) {
          return Tag(name, []);
        }
        final tagContent = values[2] is List<ASTNode>
            ? values[2] as List<ASTNode>
            : [];
        final tagFilters = values[3] is List
            ? (values[3] as List).cast<Filter>()
            : <Filter>[];
        return Tag(name, tagContent.cast(), filters: tagFilters);
      })
      .labeled('someTag');
}