Include .md file in default.md

Hello.

I’m just starting to use Grav and one of the things I miss (or have not yet found a plug-in for) is how I can include a .md file from within e.g. default.md.

As an example, if I have a default.md like:

---
title: Demo page
---

This is an example of what I want.

{{ include "some_other.md" }}

And this some_other.md file, which is in the same folder as default.md, will be inserted and rendered at the include location.

So whenever Grav will load this (default.md) page, it needs to include the raw some_other.md file and renders this at that location along with the rest of the default.md file.

I need this to include some md files I create via some scripts to be inserted into a Grav page.

Please help. :wink:

Hi @blackbird, I love to use the Page Inject Plugin within one MD file to include the content from another page - might that be of help to you too? https://github.com/getgrav/grav-plugin-page-inject
Paul

1 Like

Hello Paul,

I’ve seen this page inject plug-in but this does not do what I want. I don’t want to inject another Grav page, I want to inject just another, non Grav, markdown file sitting somewhere in the file tree within Grav.

Oh, sorry I did not catch that - I think a custom PlugIn would be needed for that. I actually something similar by creating a custom Shortcode for my Bootstrap4 Open Matter theme to read in a MD file located on a GitHub repo that might be of help: https://github.com/hibbitts-design/grav-theme-bootstrap4-open-matter/blob/master/shortcodes/MarkdownFileShortcode.php

The following code is a modified version of the Page Inject Plugin which features a third kind of injection: [plugin:markdown-inject](/route/to/file).

The plugin will look for the file starting at the Grav user directory. If the file exists it will insert it’s content.

Simply replace the page-inject.php file with the code. Take care when there’s an update of the original plugin though.

page-inject.php:

<?php
/**
 * PageInject (modified to inject plain markdown from files)
 *
 * This plugin embeds other Grav pages from markdown URLs
 *
 * Licensed under MIT, see LICENSE.
 */

namespace Grav\Plugin;

use Grav\Common\Config\Config;
use Grav\Common\Grav;
use Grav\Common\Page\Page;
use Grav\Common\Plugin;
use Grav\Common\Uri;
use RocketTheme\Toolbox\Event\Event;

class PageInjectPlugin extends Plugin
{
    /**
     * Return a list of subscribed events.
     *
     * @return array    The list of events of the plugin of the form
     *                      'name' => ['method_name', priority].
     */
    public static function getSubscribedEvents()
    {
        return [
            'onPluginsInitialized' => ['onPluginsInitialized', 0],
        ];
    }

    /**
     * Initialize configuration.
     */
    public function onPluginsInitialized()
    {
        if ($this->isAdmin()) {
            $this->active = false;
            return;
        }

        $this->enable([
            'onPageContentRaw' => ['onPageContentRaw', 0],
        ]);
    }

    /**
     * Add content after page content was read into the system.
     *
     * @param  Event  $event An event object, when `onPageContentRaw` is fired.
     */
    public function onPageContentRaw(Event $event)
    {
        /** @var Page $page */
        $page = $event['page'];

        /** @var Config $config */
        $config = $this->mergeConfig($page);

        if ($config->get('enabled') && $config->get('active')) {
            // Get raw content and substitute all formulas by a unique token
            $raw = $page->getRawContent();

            // build an anonymous function to pass to `parseLinks()`
            $function = function ($matches) use (&$page, &$twig, &$config) {

                $search = $matches[0];
                $type = $matches[1];
                $page_path = $matches[3] ?: $matches[2];
                $template = $matches[4];

                if ($type == 'markdown-inject') {
                    // "/route/to/page" from user dir
                    $user_path = $this->grav['locator']->findResource('user://');

                    if (file_exists($user_path . '/' . $page_path)) {
                        $replace = file_get_contents($user_path . '/' . $page_path);
                    }

                } else {

                    $page_path = Uri::convertUrl($page, $page_path, 'link', false, true);

                    $inject = $page->find($page_path);
                    if ($inject) {
                        // Force HTML to avoid issues with News Feeds
                        $inject->templateFormat('html');
                        if ($type == 'page-inject') {
                            if ($template) {
                                $inject->template($template);
                            }
                            $inject->modularTwig(true);
                            $replace = $inject->content();

                        } else {
                            if ($config->get('processed_content')) {
                                $replace = $inject->content();
                            } else {
                                $replace = $inject->rawMarkdown();
                            }
                        }

                    } else {

                        // replace with what you started with
                        $replace = $matches[0];
                    }
                }

                // do the replacement
                return str_replace($search, $replace, $search);
            };

            // set the parsed content back into as raw content
            $page->setRawContent($this->parseInjectLinks($raw, $function));
        }
    }

    protected function parseInjectLinks($content, $function)
    {
        $regex = '/\[plugin:(content-inject|page-inject|markdown-inject)\]\(((.*)\?template=(.*)|(.*))\)/i';
        return preg_replace_callback($regex, $function, $content);
    }
}
1 Like

Super cool @bleutzinn, thanks for sharing that! Hope you and yours are doing well.

Many thanks to @bleutzinn, your adaptation to the page inject plug-in is just what I need. Now I can inject .md sections in my pages other scripts generate off-site.

Maybe your adaptation should be part of the page inject plug-in, or maybe a new markdown-inject plug-in?

Thanks again. :slight_smile: