diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..2fff2e5347862c3de0b1c678881ee41838883fa8
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,3 @@
+## [1.1.0] - 2019-09-23
+### Added
+- PluginViewBuilder to facilitate building and rendering views for plugins
\ No newline at end of file
diff --git a/src/PluginViewBuilder.php b/src/PluginViewBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb96a8486f6d4c81c7956e90d51dd9b58f2ffa3a
--- /dev/null
+++ b/src/PluginViewBuilder.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace WPDesk\View;
+
+use WPDesk\View\Renderer\SimplePhpRenderer;
+use WPDesk\View\Resolver\ChainResolver;
+use WPDesk\View\Resolver\DirResolver;
+use WPDesk\View\Resolver\WPThemeResolver;
+
+/**
+ * Facilitates building of the default plugin renderer.
+ *
+ * @package WPDesk\View
+ */
+class PluginViewBuilder {
+	/** @var string */
+	private $plugin_dir;
+
+	/** @var string[] */
+	private $template_dirs;
+
+	/**
+	 * @param string $plugin_dir Plugin directory path(absolute path)
+	 * @param string|string[] $template_dir Directory or list of directories with templates to render
+	 */
+	public function __construct( $plugin_dir, $template_dir = 'templates' ) {
+		$this->plugin_dir = $plugin_dir;
+		if ( ! is_array( $template_dir ) ) {
+			$this->template_dirs = [ $template_dir ];
+		} else {
+			$this->template_dirs = $template_dir;
+		}
+	}
+
+	/**
+	 * Creates simple renderer that search for the templates in plugin dir and in theme/child dir.
+	 *
+	 * For example if your plugin dir is /plugin, template dir is /templates, theme is /theme, and a child theme is /child
+	 * the templates will be loaded from(order is important):
+	 * - /child/plugin/*.php
+	 * - /theme/plugin/*.php
+	 * - /plugin/templates/*.php
+	 *
+	 * @return SimplePhpRenderer
+	 */
+	public function createSimpleRenderer() {
+		$resolver = new ChainResolver();
+		$resolver->appendResolver( new WPThemeResolver( basename( $this->plugin_dir ) ) );
+		foreach ( $this->template_dirs as $dir ) {
+			$dir = trailingslashit( $this->plugin_dir ) . trailingslashit( $dir );
+			$resolver->appendResolver( new DirResolver( $dir ) );
+		}
+		return new SimplePhpRenderer( $resolver );
+	}
+
+	/**
+	 * Load templates using simple renderer.
+	 *
+	 * @param string $name Name of the template
+	 * @param string $path Additional path of the template ie. for path "path" the templates would be loaded from /plugin/templates/path/*.php
+	 * @param array $args Arguments for templates to use
+	 *
+	 * @return string Rendered template.
+	 */
+	public function loadTemplate( $name, $path = '.', $args = array() ) {
+		$renderer = $this->createSimpleRenderer();
+
+		return $renderer->render( trailingslashit( $path ) . $name, $args );
+	}
+}
\ No newline at end of file
diff --git a/tests/unit/Resolver/TestDirResolver.php b/tests/unit/Resolver/TestDirResolver.php
index 7c9876099f9b66247fc9d209febff09f26a5ff61..c8c79f3e47b678c3fdf819ec9421aca3a76c7b65 100644
--- a/tests/unit/Resolver/TestDirResolver.php
+++ b/tests/unit/Resolver/TestDirResolver.php
@@ -9,6 +9,15 @@ class TestDirResolver extends \PHPUnit\Framework\TestCase
     const TEMPLATE_FILE = 'some_template.php';
     const TEMPLATE_SUBDIR = 'templates';
 
+	public function setUp()
+	{
+		\WP_Mock::setUp();
+	}
+
+	public function tearDown()
+	{
+		\WP_Mock::tearDown();
+	}
 
     public function testCanFindInDirPath()
     {
diff --git a/tests/unit/Resolver/TestWpThemeResolver.php b/tests/unit/Resolver/TestWpThemeResolver.php
index ddcc43c5210c459d0024da728b63a0257ac2b6cd..635aeebf86afd1a2c220ee321f395b7f175ce22e 100644
--- a/tests/unit/Resolver/TestWpThemeResolver.php
+++ b/tests/unit/Resolver/TestWpThemeResolver.php
@@ -32,7 +32,7 @@ class TestThemeResolver extends \PHPUnit\Framework\TestCase
 
         \WP_Mock::userFunction('trailingslashit', [
             'return' => function ($string) {
-                return untrailingslashit($string) . '/';
+                return rtrim($string, '/\\') . '/';
             }
         ]);
 
diff --git a/tests/unit/TestPluginViewBuilder.php b/tests/unit/TestPluginViewBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcefdb7f0659f63e59aa67a6f4dc4ba77a5e0bd6
--- /dev/null
+++ b/tests/unit/TestPluginViewBuilder.php
@@ -0,0 +1,36 @@
+<?php
+
+
+use WPDesk\View\PluginViewBuilder;
+
+class TestPluginViewBuilder extends \PHPUnit\Framework\TestCase {
+	public function setUp() {
+		\WP_Mock::setUp();
+
+		\WP_Mock::userFunction('trailingslashit', [
+			'return' => function ($string) {
+				return rtrim($string, '/\\') . '/';
+			}
+		]);
+	}
+
+	public function tearDown()
+	{
+		\WP_Mock::tearDown();
+	}
+
+	public function testCanRenderUsingDir() {
+		$builder  = new PluginViewBuilder( __DIR__ . '/stub', 'template' );
+		$renderer = $builder->createSimpleRenderer();
+
+		$val     = 'val to render';
+		$args    = [ 'singleArg' => $val ];
+		$content = $renderer->render( 'file', $args );
+		$this->assertRegExp( '/template content/', $content, 'Content from stub/template/file.php should be renderer' );
+		$this->assertRegExp( "/{$val}/", $content, 'Content from stub/template/file.php should contain $val' );
+
+		$contentUsingOtherMethod = $builder->loadTemplate( 'file', '.', $args );
+		$this->assertEquals( $content, $contentUsingOtherMethod,
+			'Content should be the same no matter the method of render' );
+	}
+}
\ No newline at end of file
diff --git a/tests/unit/stub/template/file.php b/tests/unit/stub/template/file.php
new file mode 100644
index 0000000000000000000000000000000000000000..5149c9fbc93069c983bc3b5154af36542500cfba
--- /dev/null
+++ b/tests/unit/stub/template/file.php
@@ -0,0 +1 @@
+template content <?php echo $singleArg; ?>
\ No newline at end of file