[C#][.Net MVC] 8. 網站頁面外觀 View(一)
[C#][.Net MVC] 8. 外觀 View(一)
Demo範例 :[Git位置]
#目標
將網路上下載來的免費漂亮版型套進專案中,從實作中瞭解如何套版跟應用.Net提供的一些API方法,過程中或許會有許多小地方不懂,例如Html結構,View Render的機制等等,沒關係,這會在後續的篇章中慢慢補足,而此篇主要是希望讓讀者知道套版原理,並享受網頁隨著套版變漂亮的過程。
如果不方便從網路下載也無妨,我已經將下載好且解壓的版本放到Git的專案之中,如果要練習可以直接從裡面取得Source Code
#實作
## 套版前準備
###Chrome
通常我會用Chrome瀏覽器來輔助套版的工作,所以以下的操作都是針對Chrome撰寫,不過現在各家瀏覽器其實都大同小異了,只要有相對應的功能即可。
###Web Server For Chrome(非必要)
為了方便瀏覽下載的版型,可以安裝Web Server For Chrome這個套件
安裝完後應該會在Chrome的**應用程式**中看到Web Server
打開它並把資料夾選到版型的根目錄
點擊Web Server URL(s),應該就可以看到網站出現了
## 首頁套版
從Visual Studio中開啟Index.html
將所有內容複製貼到我們的/Home/Index.cshtml之中
這時候會發現第一個錯誤
###跳脫字元
原因是.Net MVC預設用的套版語法是Razor,而@是它的保留字,所以要用跳脫字元來解決,只要將@templatedco變成@@templatedco,它在顯示網頁的時候就會印出我們想要的@templatedco了
執行網站看首頁結果會發現,它怪怪的...
###Layout
首先網頁最上面那排黑黑的Header,明明我們版型的Header沒這塊,它是從哪邊長出來的?
這邊就要瞭解Layout是什麼
很多網頁都會有一個特性,那就是不管切換到哪個頁面都會有共用的區塊,以Sony頁面為例
PlayStation頁面
消費性電子>電視頁面
共通點就是Header不管到哪一頁都不會換
而如果每頁都要重新把Header套版一次會衍伸一些問題
- 重工 : 有一百頁就要把一樣的內容貼一百次
- 維護困難 : 如果想在Header多一顆按鈕,就要打開一百個頁面調整一百次
所以實務上會透過Layout來解決這問題,將全站幾乎都會共用的部分抽出來當Layout,而會變動的部分當作Body。
所以套用了新的版型還會跑出Header,那是因為Layout裡面有這個區塊
依照剛剛說的,我們把共用的區塊抽到Layout裡面去放
<!--
Hielo by TEMPLATED
templated.co @@templatedco
Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
-->
<html>
<head>
<title>Hielo by TEMPLATED</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
....
</body>
</html>
Layout調整成
<!--
Hielo by TEMPLATED
templated.co @@templatedco
Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
-->
<html>
<head>
<title>Hielo by TEMPLATED</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
@RenderBody()
@RenderSection("scripts", required: false)
<script>
@if (TempData["Message"] != null)
{
<text>alert('@TempData["Message"]')</text>
}
</script>
</body>
</html>
Index調整成
ViewBag.Title = "Home Page";
}
<!-- Header -->
<header id="header" class="alt">
<div class="logo"><a href="index.html">Hielo <span>by TEMPLATED</span></a></div>
<a href="#menu">Menu</a>
</header>
<!-- Nav -->
<nav id="menu">
<ul class="links">
<li><a href="index.html">Home</a></li>
<li><a href="generic.html">Generic</a></li>
<li><a href="elements.html">Elements</a></li>
</ul>
</nav>
<!-- Banner -->
<section class="banner full">
<article>
<img src="images/slide01.jpg" alt="" />
<div class="inner">
<header>
<p>A free responsive web site template by <a href="https://templated.co">TEMPLATED</a></p>
<h2>Hielo</h2>
</header>
</div>
</article>
<article>
<img src="images/slide02.jpg" alt="" />
<div class="inner">
<header>
<p>Lorem ipsum dolor sit amet nullam feugiat</p>
<h2>Magna etiam</h2>
</header>
</div>
</article>
<article>
<img src="images/slide03.jpg" alt="" />
<div class="inner">
<header>
<p>Sed cursus aliuam veroeros lorem ipsum nullam</p>
<h2>Tempus dolor</h2>
</header>
</div>
</article>
<article>
<img src="images/slide04.jpg" alt="" />
<div class="inner">
<header>
<p>Adipiscing lorem ipsum feugiat sed phasellus consequat</p>
<h2>Etiam feugiat</h2>
</header>
</div>
</article>
<article>
<img src="images/slide05.jpg" alt="" />
<div class="inner">
<header>
<p>Ipsum dolor sed magna veroeros lorem ipsum</p>
<h2>Lorem adipiscing</h2>
</header>
</div>
</article>
</section>
<!-- One -->
<section id="one" class="wrapper style2">
<div class="inner">
<div class="grid-style">
<div>
<div class="box">
<div class="image fit">
<img src="images/pic02.jpg" alt="" />
</div>
<div class="content">
<header class="align-center">
<p>maecenas sapien feugiat ex purus</p>
<h2>Lorem ipsum dolor</h2>
</header>
<p> Cras aliquet urna ut sapien tincidunt, quis malesuada elit facilisis. Vestibulum sit amet tortor velit. Nam elementum nibh a libero pharetra elementum. Maecenas feugiat ex purus, quis volutpat lacus placerat malesuada.</p>
<footer class="align-center">
<a href="#" class="button alt">Learn More</a>
</footer>
</div>
</div>
</div>
<div>
<div class="box">
<div class="image fit">
<img src="images/pic03.jpg" alt="" />
</div>
<div class="content">
<header class="align-center">
<p>mattis elementum sapien pretium tellus</p>
<h2>Vestibulum sit amet</h2>
</header>
<p> Cras aliquet urna ut sapien tincidunt, quis malesuada elit facilisis. Vestibulum sit amet tortor velit. Nam elementum nibh a libero pharetra elementum. Maecenas feugiat ex purus, quis volutpat lacus placerat malesuada.</p>
<footer class="align-center">
<a href="#" class="button alt">Learn More</a>
</footer>
</div>
</div>
</div>
</div>
</div>
</section
<!-- Two -->
<section id="two" class="wrapper style3">
<div class="inner">
<header class="align-center">
<p>Nam vel ante sit amet libero scelerisque facilisis eleifend vitae urna</p>
<h2>Morbi maximus justo</h2>
</header>
</div>
</section>
<!-- Three -->
<section id="three" class="wrapper style2">
<div class="inner">
<header class="align-center">
<p class="special">Nam vel ante sit amet libero scelerisque facilisis eleifend vitae urna</p>
<h2>Morbi maximus justo</h2>
</header>
<div class="gallery">
<div>
<div class="image fit">
<a href="#"><img src="images/pic01.jpg" alt="" /></a>
</div>
</div>
<div>
<div class="image fit">
<a href="#"><img src="images/pic02.jpg" alt="" /></a>
</div>
</div>
<div>
<div class="image fit">
<a href="#"><img src="images/pic03.jpg" alt="" /></a>
</div>
</div>
<div>
<div class="image fit">
<a href="#"><img src="images/pic04.jpg" alt="" /></a>
</div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer id="footer">
<div class="container">
<ul class="icons">
<li><a href="#" class="icon fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon fa-facebook"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon fa-instagram"><span class="label">Instagram</span></a></li>
<li><a href="#" class="icon fa-envelope-o"><span class="label">Email</span></a></li>
</ul>
</div>
<div class="copyright">
© Untitled. All rights reserved.
</div>
</footer>
<!-- Scripts -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/jquery.scrollex.min.js"></script>
<script src="assets/js/skel.min.js"></script>
<script src="assets/js/util.js"></script>
<script src="assets/js/main.js"></script>
#### @RenderBody()
Layout中間有一行@RenderBody()這是Razor提供的方法,意思是所有套用這個Layout的頁面,它的內容會取代@RenderBody()。
假設我們的Index內容為
那套上Layout後產生給使用者看到的完整Html就會是這樣
<!--
Hielo by TEMPLATED
templated.co @@templatedco
Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
-->
<html>
<head>
<title>Hielo by TEMPLATED</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<p>I'm Index</p>
.....
</body>
</html>
#### @RenderSection()
實務上會希望Javascript或是CSS在特定的地方載入,如果只是單純放在Index中將會變成這樣
<p>I'm Index</p>
<script src="assets/js/jquery.min.js"></script>
結果
<!--
Hielo by TEMPLATED
templated.co @@templatedco
Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
-->
<html>
<head>
<title>Hielo by TEMPLATED</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<p>I'm Index</p>
<script src="assets/js/jquery.min.js"></script>
....
</body>
</html>
此時就可以透過在Layout中挖@RenderSection()區塊來解決
Layout
<html>
<head>
....
@RenderSection("css", required: false)
</head>
<body>
@RenderBody()
@RenderSection("scripts", required: false)
....
</body>
</html>
Index
<script src="assets/js/jquery.min.js"></script>
}
@section css{
<link rel="stylesheet" href="assets/css/main.css" />
}
<p>I'm Index</p>
結果
<html>
<head>
....
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<p>I'm Index</p>
<script src="assets/js/jquery.min.js"></script>
....
</body>
</html>
@RenderSection("scripts", **required: false**)
required參數意義為
True :套用這個Layout的子版面一定要寫@section scripts{ }這個區段
False :套用這個Layout的子版面可以沒有@section scripts{ }區段
### _ViewStart
檢視Index頁面,為何它知道要套用Layout呢?其實這寫在_ViewStart.cshtml之中
_ViewStart.cshtml
Layout = "~/Views/Shared/_Layout.cshtml";
}
所有頁面如果沒有特別指定Layout的情況下,預設套用這個設定。
但這不意謂著不能自行修改,假設所有專案有兩三個頁面要套用_Layout2.cshtml,那我們可以在各自的頁面中指定Layout,而指定的Layout優先於預設。
Index
Layout = "~/Views/Shared/_Layout2.cshtml";
}
<p>I'm Index</p>
### 載入CSS、Javascript
重新調整Layout與Index內容後,頁面依然沒有正常顯示
在Chrome按下F12點擊右上角的錯誤可以得知是因為沒有載入CSS與Javascript
將Javascript與CSS移到專案之中
同時我們也刪除掉原本在專案內的Javascript與CSS
修改Index中Javascript的位置
<!-- Scripts -->
<script src="~/assets/js/jquery.min.js"></script>
<script src="~/assets/js/jquery.min.js"></script>
<script src="~/assets/js/jquery.scrollex.min.js"></script>
<script src="~/assets/js/skel.min.js"></script>
<script src="~/assets/js/util.js"></script>
<script src="~/assets/js/main.js"></script>
修改_Layout中CSS的位置
<head>
<title>Hielo by TEMPLATED</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="~/assets/css/main.css" rel="stylesheet" />
</head>
...
~/assets/css/main.css
~/assets/js/main.js
前面的 ~ 符號表示從根目錄開始算起
再次執行專案
發生錯誤,原因是BundleConfig的地方有抓原本放Javascript的資料夾但被我們砍掉了,Bundle基本上目前我們很少用到所以先暫時不理它,把內容清空不影響結果
{
// 如需統合的詳細資訊,請瀏覽 https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
}
}
執行起來後
看起來正常許多但圖片還是沒有出來,將圖片移入
#小結
已經成功將首頁移入專案之中,下一篇將來客製化將之前完成的登入頁面也套進這個漂亮的版型之中,中間將會碰到更多套版的Razor API與一些小技巧。
最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!