From 7b9f9a7812089b373394cc02275699fc28ef39b3 Mon Sep 17 00:00:00 2001
From: Franz Liedke <franz@develophp.org>
Date: Mon, 13 Mar 2017 18:08:32 +0100
Subject: [PATCH] Add link() and setCanonicalUrl() methods to the WebAppView

These make it easier for controllers to define relationships from
the current to other pages, which is important for SEO mostly.
---
 framework/core/src/Http/WebApp/WebAppView.php | 45 ++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/framework/core/src/Http/WebApp/WebAppView.php b/framework/core/src/Http/WebApp/WebAppView.php
index 5035e41ca..070c75131 100644
--- a/framework/core/src/Http/WebApp/WebAppView.php
+++ b/framework/core/src/Http/WebApp/WebAppView.php
@@ -107,6 +107,13 @@ class WebAppView
      */
     protected $foot = [];
 
+    /**
+     * A map of <link> tags to be generated.
+     *
+     * @var array
+     */
+    protected $links = [];
+
     /**
      * @var CompilerInterface
      */
@@ -219,6 +226,31 @@ class WebAppView
         $this->foot[] = $string;
     }
 
+    /**
+     * Configure a <link> tag.
+     *
+     * @param string $relation
+     * @param string $target
+     */
+    public function link($relation, $target)
+    {
+        $this->links[$relation] = $target;
+    }
+
+    /**
+     * Configure the canonical URL for this page.
+     *
+     * This will signal to search engines what URL should be used for this
+     * content, if it can be found under multiple addresses. This is an
+     * important tool to tackle duplicate content.
+     *
+     * @param string $url
+     */
+    public function setCanonicalUrl($url)
+    {
+        $this->link('canonical', $url);
+    }
+
     /**
      * Set a variable to be preloaded into the app.
      *
@@ -271,7 +303,7 @@ class WebAppView
         $view->cssUrls = $this->buildCssUrls($baseUrl);
         $view->jsUrls = $this->buildJsUrls($baseUrl);
 
-        $view->head = implode("\n", $this->head);
+        $view->head = $this->buildHeadContent();
         $view->foot = implode("\n", $this->foot);
 
         return $view->render();
@@ -337,6 +369,17 @@ class WebAppView
         }, array_filter($files));
     }
 
+    protected function buildHeadContent()
+    {
+        $html = implode("\n", $this->head);
+
+        foreach ($this->links as $rel => $href) {
+            $html .= "\n<link rel=\"$rel\" href=\"$href\" />";
+        }
+
+        return $html;
+    }
+
     /**
      * @return CompilerInterface
      */