Ad

October CMS: Share Partial Between Themes

- 1 answer

What is the simple way to share partials between themes. Assets are possible but i am having issue with whole partials. I have a multi-theme site managed/activated by sub-domain policies/logic.

SOLUTIONS /** * * Renders a requested partial in context of this component, * see Cms\Classes\[email protected] for usage. */

/**
 * @param $themeName
 * @param $partialName
 * @param $data
 * @return mixed
 * @throws \Cms\Classes\CmsException
 */
public function renderThemePartial($partialName, $themeName, $data)
{
    $theme = Theme::getActiveTheme();
    if($themeName) {
        $theme = Theme::load($themeName);
    }

    $controller = new Controller($theme);

    return $controller->renderPartial($partialName, $data);
}

/**
 *
 * Renders a requested content in context of this component,
 * see Cms\Classes\[email protected] for usage.
 */

/**
 * @param $themeName
 * @param $contentName
 * @param $data
 * @return string
 * @throws \Cms\Classes\CmsException
 */
public function renderThemeContent($contentName, $themeName, $data)
{
    $theme = Theme::getActiveTheme();
    if($themeName) {
        $theme = Theme::load($themeName);
    }

    $controller = new Controller($theme);

    return $controller->renderContent($contentName, $data);
}


public function registerMarkupTags()
{
    return [
        'functions' => [
            'partial_from_theme' => [$this, 'themePartial'],
            'content_from_theme' => [$this, 'themeContent'],
        ],
        'filters' => [
            'theme_asset'   => [$this, 'themeUrl']
        ]
    ];
}

/**
 * @param $requested
 * @return string
 */
public function themeUrl($requested)
{
    $asset = $requested[0];
    $theme = $requested[1];
    $theme = Theme::load($theme);
    $themeDir = $theme->getDirName();
    if (is_array($asset)) {
        $_url = Url::to(CombineAssets::combine($asset, themes_path().'/'.$themeDir));
    }
    else {
        $_url = Config::get('cms.themesPath', '/themes').'/'.$themeDir;
        if ($asset !== null) {
            $_url .= '/'.$asset;
        }
        $_url = Url::asset($_url);
    }
    return $_url;
}

/**
 * @param $partialName
 * @param null $themeName
 * @param array $parameters
 * @return mixed
 * @throws \Cms\Classes\CmsException
 */
public function themePartial($partialName, $themeName = null, $parameters = [])
{
    return $this->renderThemePartial($partialName, $themeName, $parameters);
}

/**
 * @param $contentName
 * @param null $themeName
 * @param array $parameters
 * @return string
 * @throws \Cms\Classes\CmsException
 */
public function themeContent($contentName, $themeName = null, $parameters = [])
{
    return $this->renderThemeContent($contentName, $themeName, $parameters);
}
Ad

Answer

I guess you can use Plugin component here you can add component to page and use its partial.

You need to define partial [ you can add as many as you like ] in component.

enter image description here

And just use that partial like below in page , now this same thing you can do in other themes as well.

enter image description here

When you change partial it will affect in all other themes like its shared across multiple themes.

Down side will be that you can not change its content from backend, you need to manually change that file from ftp or other manner.


Partial from another theme

Hmm

you can add custom twig function for that may be

In any of your plugin you can add this code

public function registerMarkupTags()
{
    return [
        'functions' => [                
            'theme_partial' => [$this, 'themePartial'],
        ]
    ];
}

public function themePartial($partialName, $themeName = null, $vars = [])
{
    $theme = Theme::getActiveTheme();
    if($themeName) {
      $theme = Theme::load($themeName);
    }
    $template = call_user_func([Partial::class, 'load'], $theme, $partialName);
    $partialContent = $template->getTwigContent();
    $html = Twig::parse($partialContent, $vars);
    return $html;
}

Now inside your theme when you want to use partial you can use

Now inside your theme when you want to use partial you can use

{{ theme_partial('call_from_other_theme', 'stemalo' ,{'name':'hardik'}) }}
                                           ^ Your theme name here.

themes/stemalo/partials/call_from_other_theme.htm content

description = "Shared Partial."

[viewBag]
==
<div id="shared_partial">
    <h1>Another Theme Partial : {{name}}</h1>
</div>

this way you can use partial from another themes.

you aksed for access to theme directory here may be you can just you need to pass theme name, and `its dynamic you can pass variable as theme name so it can pick any thing you like.

If any doubt please comment.

Ad
source: stackoverflow.com
Ad