Jump to content

Reuse views between components (and partials)

Ivan Gretsky

Recommended Posts

Good day, colleagues! How are you doing, @teppo!

I am building most of the page content with a builder built around Repeater Matrix (RM). With a great help from @Zeka I managed to make Wireframe get along with RM like this:

  1. I got the main ContentBuilder Wireframe component to render the whole content of a RM field. This component has no view of its own. But instead it generates the markup in its render() method. More on that below.
  2. There is a Wireframe component for each RM type (Type Components). Each Type Component has its view files.
  3. The main ContentBuilder component iterates through its items, determines each item's type, finds a corresponding Type Component for a type, renders it and adds the generated markup to its own output.

I find it to be a great and flexible way to generate content from RM. But I got another need, which I an not sure how to approach.

Often I need the same markup as I would get from a certain Type Component, but with the data coming not from the RM item, but from some other source (like a custom queries made in the Wireframe template controller or even from an inline PW API call). I want to reuse the view file I've got for the Type Component, but do not know how to do it the best way. Here are the possible options I came up with.

  1. Make view data generation in the Type Component conditional. So the component knows, when it is called from the RM context and uses data from the corresponding RM item. And when it is used in the other context, it uses other data. The context could be determined from the parameters passed to the component constructor. The question here is "Does it looks like too much for a simple component?"
  2. Make another component and make it use the same view. The question is "is it possible to share views between components and how?"
  3. Use Type Component view as a partial with parameters, passing in all the necessary vars. The question here is related to the discussion in this topic and it reads "is it possible to use a file not from the /partials catalog as a partial with parameters and how?" I guess, that this syntax would be perfect it would exist:
    <?= $partials->get("components/a/deafault.php", ['headline' => 'Hi!']) ?>
    <?= // Note the path is from the templates root. It could be an absolute path.?>

I am leaning towards the 3rd option (if it was only possible))) But could you please share your  thought on the whole issue. How would you recommend to handle it?


Link to comment
Share on other sites

  • Ivan Gretsky changed the title to Reuse views between components (and partials)

Hi @Ivan Gretsky

Probably you can override render method of Type Component so it will render some partial. 

<?php namespace Wireframe\Blocks;

use ProcessWire\Wireframe;

class BlockTypeBlogTitle extends Block
	protected function getDefaultViewData(): array
		return [
			'title' => $this->item->get('title')
	public function ___render(): string
		return Wireframe::partial('somepartial', $this->getDefaultViewData());

In this way you will be able to use same partial output both for components and partials. 


  • Like 1
Link to comment
Share on other sites

I have not thought about it)

That would force us to use the templates root based partials all the time. This is an option. But it feels like too much of a deviation from the mainline usage.

It seems to me that the best way would be distinguish between full and relative paths, so we could render a partial from a non-standard path time to time, leaving the defaults for common usage.

Anyway, thanks @Zeka for digging in this and giving such creative options!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...