From a9aca7d4fecfdeb2ab9887faca3cd61b14c7e707 Mon Sep 17 00:00:00 2001 From: Kevin MacMartin Date: Thu, 26 Apr 2018 20:26:18 -0400 Subject: [PATCH] Amalgamate the api route controller functionality into a single ApiController, and implement both vue component and traditional blade versions of a blog page on the public facing part of the site --- ...iptionController.php => ApiController.php} | 38 ++++++++- app/Http/Controllers/ContactController.php | 35 -------- app/Models/Blog.php | 36 +++++++++ resources/assets/js/app.js | 2 + resources/assets/sass/_var.scss | 2 +- resources/assets/sass/pages/_blog.scss | 81 +++++++++++++++++++ resources/components/pages/blog.vue | 66 +++++++++++++++ resources/components/sections/nav.vue | 1 + routes/api.php | 12 ++- .../resources/views/pages/blog.blade.php | 45 +++++++++++ .../resources/views/sections/nav.blade.php | 1 + traditional-bootstrap/routes/web.php | 4 + 12 files changed, 283 insertions(+), 40 deletions(-) rename app/Http/Controllers/{SubscriptionController.php => ApiController.php} (53%) delete mode 100644 app/Http/Controllers/ContactController.php create mode 100644 resources/assets/sass/pages/_blog.scss create mode 100644 resources/components/pages/blog.vue create mode 100644 traditional-bootstrap/resources/views/pages/blog.blade.php diff --git a/app/Http/Controllers/SubscriptionController.php b/app/Http/Controllers/ApiController.php similarity index 53% rename from app/Http/Controllers/SubscriptionController.php rename to app/Http/Controllers/ApiController.php index 8c91f7c..28f3fd1 100644 --- a/app/Http/Controllers/SubscriptionController.php +++ b/app/Http/Controllers/ApiController.php @@ -1,11 +1,45 @@ validate($request, [ + 'name' => 'required', + 'email' => 'required|email', + 'message' => 'required' + ]); + + $contact = new Contact; + $contact->name = $request['name']; + $contact->email = $request['email']; + $contact->message = $request['message']; + $contact->save(); + + // Send the email if the MAIL_SENDTO variable is set + if (env('MAIL_SENDTO') != null) { + Mail::send('email.contact', [ 'contact' => $contact ], function($mail) use ($contact) { + $mail->from(env('MAIL_SENDFROM'), env('APP_NAME')) + ->to(env('MAIL_SENDTO')) + ->subject('Contact form submission'); + }); + } + + return 'success'; + } public function postSubscriptionSubmit(Request $request) { diff --git a/app/Http/Controllers/ContactController.php b/app/Http/Controllers/ContactController.php deleted file mode 100644 index be99deb..0000000 --- a/app/Http/Controllers/ContactController.php +++ /dev/null @@ -1,35 +0,0 @@ -validate($request, [ - 'name' => 'required', - 'email' => 'required|email', - 'message' => 'required' - ]); - - $contact = new Contact; - $contact->name = $request['name']; - $contact->email = $request['email']; - $contact->message = $request['message']; - $contact->save(); - - // Send the email if the MAIL_SENDTO variable is set - if (env('MAIL_SENDTO') != null) { - Mail::send('email.contact', [ 'contact' => $contact ], function($mail) use ($contact) { - $mail->from(env('MAIL_SENDFROM'), env('APP_NAME')) - ->to(env('MAIL_SENDTO')) - ->subject('Contact form submission'); - }); - } - - return 'success'; - } - -} diff --git a/app/Models/Blog.php b/app/Models/Blog.php index 34831fa..ebb6cd8 100644 --- a/app/Models/Blog.php +++ b/app/Models/Blog.php @@ -2,7 +2,9 @@ namespace App\Models; +use Parsedown; use Illuminate\Database\Eloquent\Model; +use App\User; class Blog extends DashboardModel { @@ -22,4 +24,38 @@ class Blog extends DashboardModel [ 'name' => 'tags', 'type' => 'text' ], [ 'name' => 'header-image', 'title' => 'Header Image', 'type' => 'image', 'delete' => true ] ]; + + public static function getBlogEntries() + { + $blog_entries = []; + + foreach (self::orderBy(self::$dashboard_sort_column, self::$dashboard_sort_direction)->get() as $blog_entry) { + // Add the name of the user that created the post + $blog_entry['username'] = User::find($blog_entry->user_id)->name; + + // Add a string with the date and time the post was made + $blog_entry['date'] = date('M j, Y @ g:iA', strtotime($blog_entry->created_at)); + + // Convert the markdown in the body to html + $blog_entry['body'] = Parsedown::instance()->setBreaksEnabled(true)->setMarkupEscaped(true)->parse($blog_entry['body']); + + // Replace the tags string with an array + $tags = []; + + foreach (explode(';', $blog_entry['tags']) as $tag) { + array_push($tags, $tag); + } + + $blog_entry['tags'] = $tags; + + // Add the header image if one exists + $header_image_path = '/uploads/blog/img/' . $blog_entry->id . '-header-image.jpg'; + $blog_entry['headerimage'] = file_exists(base_path() . '/public' . $header_image_path) ? $header_image_path : ''; + + // Add the processed blog entry to the array + array_push($blog_entries, $blog_entry); + } + + return $blog_entries; + } } diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index ecde5c3..f8a7e42 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -17,6 +17,7 @@ Vue.http.headers.common["X-CSRF-TOKEN"] = env.csrfToken; // Import page components import HomePage from "pages/home.vue"; +import BlogPage from "pages/blog.vue"; import ContactPage from "pages/contact.vue"; import Error404Page from "pages/error404.vue"; @@ -36,6 +37,7 @@ const router = new VueRouter({ routes: [ { path: "/", component: HomePage }, + { path: "/blog", component: BlogPage }, { path: "/contact", component: ContactPage }, { path: "/*", component: Error404Page } ], diff --git a/resources/assets/sass/_var.scss b/resources/assets/sass/_var.scss index a162c52..2dd51fa 100644 --- a/resources/assets/sass/_var.scss +++ b/resources/assets/sass/_var.scss @@ -28,7 +28,7 @@ $c-accent: #fa7921; // accent $c-error: #fa2036; // error // Values -$nav-link-count: 2; +$nav-link-count: 3; // Sizes $nav-height-desktop: 60px; diff --git a/resources/assets/sass/pages/_blog.scss b/resources/assets/sass/pages/_blog.scss new file mode 100644 index 0000000..1d4ba89 --- /dev/null +++ b/resources/assets/sass/pages/_blog.scss @@ -0,0 +1,81 @@ +.blog-page-component { + padding: $grid-gutter-width 0px; + + h1 { + margin-bottom: $grid-gutter-width; + } + + .blog-entry { + border: 1px solid lighten($c-base, 75%); + border-radius: 5px; + + @include media-breakpoint-up(md) { + display: flex; + } + + + &:not(:last-child) { + margin-bottom: $grid-gutter-width; + } + + &-header-image { + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + + @include media-breakpoint-down(sm) { + @include aspect-ratio(3, 1); + width: 100%; + } + + @include media-breakpoint-up(md) { + width: 35%; + flex-shrink: 0; + } + } + + &-content { + padding: 25px; + + @include media-breakpoint-up(md) { + display: flex; + flex-direction: row; + flex-grow: 1; + flex-wrap: wrap; + } + + > * { + width: 100%; + } + + &-title { + @include font-sans-semibold; + margin-bottom: $grid-gutter-width; + font-size: 25px; + text-align: center; + text-transform: uppercase; + } + + &-info { + color: lighten($c-text, 30%); + } + + &-body { + margin: ($grid-gutter-width / 2) 0px; + } + + &-taglist { + width: 100%; + + &-item { + margin-right: 5px; + display: inline-block; + padding: 3px 8px; + border-radius: 3px; + background-color: $c-accent; + color: $c-text-light; + } + } + } + } +} diff --git a/resources/components/pages/blog.vue b/resources/components/pages/blog.vue new file mode 100644 index 0000000..1304ecb --- /dev/null +++ b/resources/components/pages/blog.vue @@ -0,0 +1,66 @@ + + + diff --git a/resources/components/sections/nav.vue b/resources/components/sections/nav.vue index 420f249..a4df694 100644 --- a/resources/components/sections/nav.vue +++ b/resources/components/sections/nav.vue @@ -40,6 +40,7 @@ navLinks: [ { path: "/", title: "Home" }, + { path: "/blog", title: "Blog" }, { path: "/contact", title: "Contact" } ] }; diff --git a/routes/api.php b/routes/api.php index bcbe5e9..09fe853 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,11 +17,19 @@ Route::middleware('auth:api')->get('/user', function(Request $request) { return $request->user(); }); +/* +|-------------------------------------------------------------------------- +| Get Routes +|-------------------------------------------------------------------------- +*/ + +Route::get('/blog-entries', 'ApiController@getBlogEntries'); + /* |-------------------------------------------------------------------------- | Post Routes |-------------------------------------------------------------------------- */ -Route::post('/contact-submit', 'ContactController@postContactSubmit'); -Route::post('/subscription-submit', 'SubscriptionController@postSubscriptionSubmit'); +Route::post('/contact-submit', 'ApiController@postContactSubmit'); +Route::post('/subscription-submit', 'ApiController@postSubscriptionSubmit'); diff --git a/traditional-bootstrap/resources/views/pages/blog.blade.php b/traditional-bootstrap/resources/views/pages/blog.blade.php new file mode 100644 index 0000000..985910c --- /dev/null +++ b/traditional-bootstrap/resources/views/pages/blog.blade.php @@ -0,0 +1,45 @@ +@extends('templates.public', [ 'title' => 'Blog' ]) + +@section('content') +
+
+
+
+

Blog

+ + @foreach(App\Models\Blog::getBlogEntries() as $entry) +
+ @if($entry['headerimage'] != '') +
+
+ @endif + +
+

{{ $entry['title'] }}

+ + + +

+ {!! $entry['body'] !!} +

+ + +
+
+ @endforeach +
+
+
+
+@endsection diff --git a/traditional-bootstrap/resources/views/sections/nav.blade.php b/traditional-bootstrap/resources/views/sections/nav.blade.php index 7b6b33e..c6435b2 100644 --- a/traditional-bootstrap/resources/views/sections/nav.blade.php +++ b/traditional-bootstrap/resources/views/sections/nav.blade.php @@ -11,6 +11,7 @@ diff --git a/traditional-bootstrap/routes/web.php b/traditional-bootstrap/routes/web.php index e1c1173..f1cd405 100644 --- a/traditional-bootstrap/routes/web.php +++ b/traditional-bootstrap/routes/web.php @@ -69,6 +69,10 @@ Route::get('/', function() { return view('pages.index'); }); +Route::get('/blog', function() { + return view('pages.blog'); +}); + Route::get('/contact', function() { return view('pages.contact'); });