Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Markdown Content Bundle Laravel Package

asm/markdown-content-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require asm/markdown-content-bundle

Add the bundle to AppKernel.php:

new Asm\MarkdownContentBundle\AsmMarkdownContentBundle(),
  1. Configure: Add to config.yml:

    asm_markdown_content:
        content_directory: '%kernel.root_dir%/../src/AppBundle/Resources/markdown'
        route_prefix: 'content'
        markdown_provider: 'parsedown'  # or 'php-markdown'
    
  2. Create Markdown Files: Place .md files in src/AppBundle/Resources/markdown/ (e.g., about.md). Example content:

    ---
    title: About Us
    description: Learn more about our team
    ---
    # Welcome to Our Team
    This is a markdown file rendered via the bundle.
    
  3. Access Content: Visit /content/about (or /en_US/content/about if using locales).


Implementation Patterns

Routing and Content Access

  • Dynamic Routes: The bundle auto-generates routes for all .md files under content_directory. Example: about.md/content/about.
  • Locale Support: Enable locale_url: true in config to use /en_US/content/about.
  • Twig Integration: Access content in templates via:
    {{ content.data.title }}  {# Front matter title #}
    {{ content.html }}        {# Rendered HTML #}
    

Hooks for Custom Logic

  • Pre-Content Hooks: Modify raw markdown (e.g., inject placeholders).

    # services.yml
    app.markdown_hook:
        class: AppBundle\Hook\CustomPreHook
        tags:
            - { name: asm_markdown_content.hook, alias: custom_pre }
    
    // CustomPreHook.php
    class CustomPreHook implements HookDataInterface {
        public function getType() { return 'pre'; }
        public function workContent(array $content) {
            $content['content'][] = '---\ncustom: injected\n---';
            return $content;
        }
    }
    
  • Post-Content Hooks: Modify HTML output (e.g., add classes).

    class CustomPostHook implements HookContentInterface {
        public function getType() { return 'post'; }
        public function workContent(array $content) {
            $content['html'] = str_replace('<h1>', '<h1 class="custom">', $content['html']);
            return $content;
        }
    }
    

Templating Overrides

  • Override default templates by copying:
    • vendor/asm/markdown-content-bundle/Resources/views/layout.html.twigAppBundle/Resources/views/layout.html.twig
    • vendor/asm/markdown-content-bundle/Resources/views/Content/index.html.twigAppBundle/Resources/views/Content/index.html.twig
  • Use Twig variables:
    {# content.data #}  {# Front matter #}
    {# content.html #}  {# Rendered content #}
    {# content.path #}  {# File path #}
    

Exporting Static Pages

  • Generate static HTML for deployment:
    php app/console asm:markdown:export /path/to/static/dir
    
  • Optional: Import from another directory:
    php app/console asm:markdown:export /static/dir -i /source/markdown/dir
    

Gotchas and Tips

Common Pitfalls

  1. File Permissions: Ensure content_directory is writable if using hooks or export.

    chmod -R 755 src/AppBundle/Resources/markdown
    
  2. Front Matter Parsing:

    • No whitespace before --- in front matter (e.g., --- must be the first line).
    • YAML validation: Invalid YAML (e.g., unquoted keys with special chars) breaks parsing. Fix: Use quotes or escape characters (e.g., "key: value" or key\: value).
  3. Route Conflicts: Avoid naming .md files to match existing Symfony routes (e.g., contact.md if /contact is a route). Solution: Use route_prefix to namespace routes (e.g., content/contact).

  4. Parser Dependencies:

    • parsedown (default) is lighter but lacks some PHP-Markdown features (e.g., tables).
    • Switch parsers in config.yml:
      markdown_provider: 'php-markdown'
      
    • Install missing parser:
      composer require michelf/php-markdown
      
  5. Locale Handling:

    • Directory structure: Place files in content/{locale}/ (e.g., content/en_US/about.md).
    • Fallback: If a locale isn’t found, the bundle returns a 404. Ensure default locale is set in config.yml:
      framework:
          default_locale: en_US
      

Debugging Tips

  1. Check Loaded Content: Dump content in a Twig template or controller:

    {{ dump(content) }}
    

    Or in PHP:

    $content = $this->get('asm_markdown_content.content_loader')->load('about');
    var_dump($content);
    
  2. Hook Debugging:

    • Log hook execution in workContent():
      error_log(print_r($content, true));
      
    • Verify hook order: Hooks run in registration order (first registered = first executed).
  3. Export Issues:

    • Ensure absolute_export_dir is writable.
    • Check for symlink issues if using non-absolute paths.

Extension Points

  1. Custom Loaders: Implement ContentLoaderInterface for non-file sources (e.g., S3, API). Example:

    class ApiContentLoader implements ContentLoaderInterface {
        public function load($path) {
            $apiResponse = file_get_contents("https://api.example.com/$path.md");
            return ['content' => $apiResponse, 'data' => []];
        }
    }
    

    Register as a service:

    app.api_loader:
        class: AppBundle\Loader\ApiContentLoader
        tags:
            - { name: asm_markdown_content.content_loader, alias: api }
    
  2. Custom Parsers: Implement ParserInterface for non-Markdown formats (e.g., BBCode). Example:

    class BbcodeParser implements ParserInterface {
        public function parse($content) {
            return convertBbcodeToHtml($content);
        }
    }
    

    Register:

    app.bbcode_parser:
        class: AppBundle\Parser\BbcodeParser
        tags:
            - { name: asm_markdown_content.parser, alias: bbcode }
    
  3. Caching: The bundle lacks built-in caching. Add a post-hook to cache rendered HTML:

    class CacheHook implements HookContentInterface {
        public function getType() { return 'post'; }
        public function workContent(array $content) {
            $cacheKey = 'markdown_' . md5($content['path']);
            $cache = $this->get('cache.app');
            $cache->set($cacheKey, $content['html'], 3600); // Cache for 1 hour
            return $content;
        }
    }
    
  4. Performance:

    • Pre-rendering: Use the export command to generate static HTML during deployment.
    • Compiler Pass: For large sites, create a compiler pass to pre-load and cache file listings:
      class MarkdownContentPass implements CompilerPassInterface {
          public function process(ContainerBuilder $container) {
              $loader = $container->getParameter('asm_markdown_content.content_directory');
              // Pre-cache file list
          }
      }
      
      Register in services.yml:
      services:
          app.markdown_compiler_pass:
              class: AppBundle\DependencyInjection\Compiler\MarkdownContentPass
              tags:
                  - { name: kernel.compiler_pass }
      

Configuration Quirks

  • content_path_depth: Set in config.yml to control subdirectory depth for routing:

    asm_markdown_content:
        content_path_depth: 2  # Routes: /content/subdir/file
    

    Default: 1 (routes like /content/subdir/file become /content/file).

  • Route Generation: The bundle uses FOSRouterBundle-like syntax. Override route generation by extending the ContentRouter service:

    app.content_router:
        class: AppBundle\Routing\CustomContentRouter
        decorates: asm_markdown_content.content_router
        arguments: ['@app.content_router.inner']
    

Migration Notes

  • From v0.3 to v0.4:
    • Front matter replaced
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity