octobercmsoctobercms-pluginsoctober-partial

Share Partials/Components between 2 Plugins


Is there a way to access partials from another component or another plugin?

I have a modal component showing some sort of message. Now I have another component showing a complex form in a modal dialog. They reside in 2 plugins.


Solution

  • Yes, inside of a plugin component you can access partials from both another component in the same plugin (you'd setup a shared partial), and components and partials from other plugins.

    For accessing shared partials between components in the same plugin, see this section of the docs.:

    Multiple components can share partials by placing the partial file in a directory called components/partials. The partials found in this directory are used as a fallback when the usual component partial cannot be found. For example, a shared partial located in /plugins/acme/blog/components/partials/shared.htm can be displayed on the page by any component using:

    {% partial '@shared' %}
    

    For accessing components or partials from another plugin inside of your component plugin, see the following examples of the Foo and Bar plugins:

    plugins/montanabanana/foo/Plugin.php:

    <?php namespace MontanaBanana\Foo;
    
    use System\Classes\PluginBase;
    
    class Plugin extends PluginBase
    {
        public function registerComponents()
        {
            return [
                'MontanaBanana\Foo\Components\Thud' => 'thud'
            ];
        }
    
        public function registerSettings()
        {
        }
    }
    

    plugins/montanabanana/foo/components/Thud.php

    <?php
    
    namespace MontanaBanana\Foo\Components;
    
    class Thud extends \Cms\Classes\ComponentBase
    {
        public function componentDetails()
        {
            return [
                'name' => 'Thud Component',
                'description' => ''
            ];
        }
    }
    

    plugins/montanabanana/foo/components/thud/default.htm

    <pre>Thud component, default.htm</pre>
    

    plugins/montanabanana/foo/components/thud/partial.htm

    <pre>This is the thud partial</pre>
    

    Ok, so we have setup the Foo plugin that registers a Thud component. That component has some basic default markup in it as well as a partial in the component folder. Now, let's setup another plugin that has a component Grunt which can use this component and partial Thud from Foo:

    plugins/montanabanana/bar/Plugin.php

    <?php namespace MontanaBanana\Bar;
    
    use System\Classes\PluginBase;
    
    class Plugin extends PluginBase
    {
        // We should require the plugin we are pulling from
        public $require = ['MontanaBanana.Foo'];
    
        public function registerComponents()
        {
            return [
                'MontanaBanana\Bar\Components\Grunt' => 'grunt'
            ];
        }
    
        public function registerSettings()
        {
        }
    }
    

    plugins/montanabanana/bar/components/grunt/default.htm

    <pre>Grunt component, default.htm</pre>
    
    {% component 'thud' %}
    
    {% partial 'thud::partial' %}
    

    Note that in the above component default markup file for the Grunt component in Bar, we have called both the Thud component and the partial.htm partial from the Thud component.

    We're not quite done though, and I am pretty sure it has to be done this way (though there may be a more elegant way I don't know about), but we have define both components on the page we want to call this all from:

    themes/your-theme/pages/example.htm

    title = "Example"
    url = "/example"
    
    [grunt]
    [thud]
    ==
    {% component 'grunt' %}
    

    The output of which is:

    <pre>Grunt component, default.htm</pre>
    <pre>Thud component, default.htm</pre>
    <pre>This is the thud partial</pre>
    

    I don't fully understand what you're asking in the second part of your question, but hopefully the above helps you solve it.