Rozbudowując mój poprzedni wpis na temat szybkiego startu w Frameworku Laravel Szybki start z Laravel 5.4 chciałbym zaproponować kolejny cykl, w którym zbudujemy od podstaw konkretną aplikację – wypożyczalnię sprzętu wodnego. Aplikacja opierać się będzie na Laravel 5.4, przy czym panel zarządzający spróbujemy wykonać w Angular 5 – w tym celu potrzebować będziemy chociaż szczątkowego API. Zaczniemy jednak od tego, co widzieć będą nasi klienci., a sam panel administracyjny zostawimy na koniec. Do dzieła!
W celu przyjemniejszego korzystania z systemu, spróbujmy dodać do naszego kodu przykładowy szablon html. Dzięki temu od razu będziemy mogli ewentualne widoki dopasowywać do generalnego layoutu. Przykładowym szablonem niech będzie ten z linka poniżej:
http://www.free-css.com/free-css-templates/page194/yacht-club
Jest to prosty, darmowy szablon w HTML. Nie czekająć ściągamy go na dysk i rozpakowujemy. Od razu rzuci nam się w oczy plik index.html a także podkatalogi css, fonts, img i js, które przenosimy do naszej aplikacji do katalogu public. Pliki z zdjęciami sprzętu wodnego (pic1.jpg, pic2,jpg i pic3.jpg) przenosimy do katalogu img/vehicles i nadajemy kolejno nazwy 1.jpg, 2.jpg, 3.jpg. Po tych czynnościach katalog public będzie wyglądał następująco:
Mając przekopiowane pliki możemy przejść do edycji naszego widoku. Domyślnie Laravel stworzył jeden plik będący szablonem całej aplikacji. Plik ten znajduje się w katalogu resources/views/layouts/app.blade.php.
Gdy go otworzymy, ujrzymy sporo wygenerowanego kodu, jednakże dla nas najważniejsza będzie informacja o umiejscowieniu elementów:
- tytułu strony
- plików css i js
- zawartości danego widoku, czyli miejsca gdzie w szablonie ma być osadzany kod wygenerowany przez widoki. Miejsce to oznaczone będzie znacznikiem @yield(‘content’). Widzimy więc, że do naszego szablonu musimy przekazywać zmienną content, której zawartość będzie wypełniała wyznaczone miejsce. Dzięki temu możemy raz zdefiniowany szablon wykorzystywać w wielu miejscach aplikacji, zmieniając jedynie wyświetlaną zawartość.
- ustawienia języka strony (pierwsza linijka)
Wszystkie te powyższe zmienne musimy umiejscowić w naszym nowym szablonie, najprościej więc będzie przekopiować całą zawartość pliku index.html do pliku app.blade.php i wszystkie powyższe miejsca zaktualizować, czyli:
- ustawić język – <html lang=”{{ app()->getLocale() }}”>
- poprawić wszelkie ścieżki do plików css i js odwołaniami względnymi, np: <link href=”{{ asset(‘css/bootstrap.css’) }}” rel=”stylesheet”>
<script src=”{{ asset(‘js/jquery.js’) }}”></script> - po komentarzu <!– Content –> wstawić nasz znacznik zawartości @yield(‘content’)
Tak by całość prezentowała się następująco:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
<!DOCTYPE html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap --> <link href="{{ asset('css/bootstrap.css') }}" rel="stylesheet"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!--Google Fonts--> <link href='http://fonts.googleapis.com/css?family=Belgrano|Courgette&subset=latin,latin-ext' rel='stylesheet' type='text/css'> <!--Bootshape--> <link href="{{ asset('css/bootshape.css') }}" rel="stylesheet"> <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> </head> <body> <!-- Navigation bar --> <div class="navbar navbar-default navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#"> {{ config('app.name', 'Laravel') }}</a> </div> <nav role="navigation" class="collapse navbar-collapse navbar-right"> <ul class="navbar-nav nav"> <li class="active"><a href="#">Home</a></li> <li class="dropdown"> <a data-toggle="dropdown" href="#" class="dropdown-toggle">Yachts <b class="caret"></b></a> <ul class="dropdown-menu"> <li class="active"><a href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 3</a></li> <li class="divider"></li> <li><a href="#">All Items</a></li> </ul> </li> <li><a href="#">Destinations</a></li> <li><a href="#">License</a></li> <li><a href="#">Contacts</a></li> </ul> </nav> </div> </div><!-- End Navigation bar --> <!-- Slide gallery --> <div class="jumbotron"> <div class="container"> <div class="col-xs-12"> <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> <li data-target="#carousel-example-generic" data-slide-to="2"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner"> <div class="item active"> <img src="{{ asset('img/carousel1.jpg') }}" alt=""> <div class="carousel-caption"> </div> </div> <div class="item"> <img src="{{ asset('img/carousel2.jpg') }}" alt=""> <div class="carousel-caption"> </div> </div> <div class="item"> <img src="{{ asset('img/carousel3.jpg') }}" alt=""> <div class="carousel-caption"> </div> </div> </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a class="right carousel-control" href="#carousel-example-generic" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a> </div> </div> </div><!-- End Slide gallery --> </div> <!-- Thumbnails --> <div class="container thumbs"> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img src="img/pic1.jpg" alt="" class="img-responsive"> <div class="caption"> <h3 class="">Motor</h3> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p> <div class="btn-toolbar text-center"> <a href="#" role="button" class="btn btn-primary pull-right">Terminy</a> </div> </div> </div> </div> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img src="img/pic2.jpg" alt="" class="img-responsive"> <div class="caption"> <h3 class="">Luxury</h3> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p> <div class="btn-toolbar text-center"> <a href="#" role="button" class="btn btn-primary pull-right">Details</a> </div> </div> </div> </div> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img src="img/pic3.jpg" alt="" class="img-responsive"> <div class="caption"> <h3 class="">Sailboats</h3> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p> <div class="btn-toolbar text-center"> <a href="#" role="button" class="btn btn-primary pull-right">Details</a> </div> </div> </div> </div> </div><!-- End Thumbnails --> <!-- Content --> @yield('content') <div class="container"> <div class=""> <h3 class="">Welcome</h3> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries.</p> </div> <div class="row"> <div class="col-sm-8"> <h3 class="">About</h3> <img src="img/about.jpg" alt="" class="img-responsive"> <br> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries. Lorem Ipsum is simply dummy text of.</p> </div> <div class="col-sm-4"> <h3 class="">News & Events</h3> <div class="event"> <div class="text-right date">01/22/2014</div> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industr y. Lorem Ipsum has been the industry's standard dummy text ever since the 1500.</p> <div class="text-right"> <a href="#">See more...</a> </div> </div> <div class="event"> <div class="text-right date">01/22/2014</div> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industr y. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p> <div class="text-right"> <a href="#">See more...</a> </div> </div> <div class="event"> <div class="text-right date">01/22/2014</div> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industr y. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p> <div class="text-right"> <a href="#">See more...</a> </div> </div> </div> </div> </div><!-- End Content --> <!-- Footer --> <div class="footer text-center"> <p>© 2014 Yacht Club. All Rights Reserved. Proudly created by <a href="http://bootshape.com">Bootshape.com</a></p> </div><!-- End Footer --> @if (Auth::guest()) <li><a href="{{ route('login') }}">Login</a></li> <li><a href="{{ route('register') }}">Register</a></li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> {{ Auth::user()->name }} <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li> <a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout </a> <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> </li> </ul> </li> @endif <!-- Scripts --> <script src="{{ asset('js/jquery.js') }}"></script> <script src="{{ asset('js/bootstrap.min.js') }}"></script> <script src="{{ asset('js/bootshape.js') }}"></script> <!-- Scripts --> <script src="{{ asset('js/app.js') }}"></script> <!-- Scripts --> <script src="{{ asset('js/app.js') }}"></script> </body> </html> |
Pozostaje nam tylko uruchomić stronę (pamiętamy o uruchomieniu serwera poprzez php artisan serve):
http://127.0.0.1:8000/login
zalogować się i zobaczyć nasz komunikat powitalny:
Widzimy również, iż generalnie cały frontend opiera się na naszym nowym szablonie graficznym, włączając w to formularze rejestracji i logowania.
W tym miejscu warto zmienić naszą stronę główną. Przejdźy do pliku routes/web.php i w linijce 20stej zaktualizujmy nasz routing z:
1 |
Route::get('/home', 'HomeController@index')->name("home"); |
na
1 |
Route::get('/', 'HomeController@index')->name("home"); |
W następnym odcinku spróbujemy dodać nowy model maszyny, stworzymy odpowiednie rekordy w bazie, a także zamienimy statyczne obrazki jachtów na dane dynamicznie pobierane z bazy. Stay tuned!
drobny błąd zamiast:
Route::get(‚/’, ‚HomeController@index’)->name(‚home’);
powinno być:
Route::get(‘/’, ‘HomeController@index’)->name(‘home’);
Słuszna uwaga, WordPress automatycznie zamienił “” na ,”. Dziękuję za zauważenie!