mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-12-22 09:40:23 -05:00
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
This commit is contained in:
parent
b83213c16e
commit
a9aca7d4fe
12 changed files with 283 additions and 40 deletions
|
@ -1,11 +1,45 @@
|
|||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Newsletter;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Newsletter;
|
||||
use App\Models\Blog;
|
||||
use App\Models\Contact;
|
||||
use App\Models\Subscriptions;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SubscriptionController extends Controller {
|
||||
class ApiController extends Controller {
|
||||
|
||||
public function getBlogEntries()
|
||||
{
|
||||
return Blog::getBlogEntries();
|
||||
}
|
||||
|
||||
public function postContactSubmit(Request $request)
|
||||
{
|
||||
$this->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)
|
||||
{
|
|
@ -1,35 +0,0 @@
|
|||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Mail;
|
||||
use App\Models\Contact;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ContactController extends Controller {
|
||||
|
||||
public function postContactSubmit(Request $request)
|
||||
{
|
||||
$this->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';
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
2
resources/assets/js/app.js
vendored
2
resources/assets/js/app.js
vendored
|
@ -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 }
|
||||
],
|
||||
|
|
2
resources/assets/sass/_var.scss
vendored
2
resources/assets/sass/_var.scss
vendored
|
@ -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;
|
||||
|
|
81
resources/assets/sass/pages/_blog.scss
vendored
Normal file
81
resources/assets/sass/pages/_blog.scss
vendored
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
66
resources/components/pages/blog.vue
Normal file
66
resources/components/pages/blog.vue
Normal file
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class="blog-page-component">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-10 offset-lg-1 col-xl-8 offset-xl-2 col-xxl-6 offset-xxl-3">
|
||||
<h1>Blog</h1>
|
||||
|
||||
<div
|
||||
v-for="entry in blogEntries"
|
||||
class="blog-entry">
|
||||
|
||||
<div
|
||||
v-if="entry.headerimage !== ''"
|
||||
class="blog-entry-header-image"
|
||||
:style="{ backgroundImage: 'url(' + entry.headerimage + ')' }">
|
||||
</div>
|
||||
|
||||
<div class="blog-entry-content">
|
||||
<h2 class="blog-entry-content-title">{{ entry.title }}</h2>
|
||||
|
||||
<div class="blog-entry-content-info">
|
||||
<span class="blog-entry-content-info-name">{{ entry.username }}</span> |
|
||||
<span class="blog-entry-content-info-date">{{ entry.date }}</span>
|
||||
</div>
|
||||
|
||||
<p class="blog-entry-content-body" v-html="entry.body"></p>
|
||||
|
||||
<div class="blog-entry-content-taglist">
|
||||
<span
|
||||
v-for="tag in entry.tags"
|
||||
class="blog-entry-content-taglist-item">
|
||||
|
||||
{{ tag }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
blogEntries: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
populateBlogEntries() {
|
||||
this.$http.get("/api/blog-entries" + env.apiToken).then((response) => {
|
||||
this.blogEntries = response.body;
|
||||
}, (response) => {
|
||||
console.log("Failed to retrieve blog entries");
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.populateBlogEntries();
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
navLinks: [
|
||||
{ path: "/", title: "Home" },
|
||||
{ path: "/blog", title: "Blog" },
|
||||
{ path: "/contact", title: "Contact" }
|
||||
]
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
|
|
45
traditional-bootstrap/resources/views/pages/blog.blade.php
Normal file
45
traditional-bootstrap/resources/views/pages/blog.blade.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
@extends('templates.public', [ 'title' => 'Blog' ])
|
||||
|
||||
@section('content')
|
||||
<div class="blog-page-component">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-10 offset-lg-1 col-xl-8 offset-xl-2 col-xxl-6 offset-xxl-3">
|
||||
<h1>Blog</h1>
|
||||
|
||||
@foreach(App\Models\Blog::getBlogEntries() as $entry)
|
||||
<div class="blog-entry">
|
||||
@if($entry['headerimage'] != '')
|
||||
<div
|
||||
class="blog-entry-header-image"
|
||||
style="background-image: url({{ $entry['headerimage'] }})">
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="blog-entry-content">
|
||||
<h2 class="blog-entry-content-title">{{ $entry['title'] }}</h2>
|
||||
|
||||
<div class="blog-entry-content-info">
|
||||
<span class="blog-entry-content-info-name">{{ $entry['username'] }}</span> |
|
||||
<span class="blog-entry-content-info-date">{{ $entry['date'] }}</span>
|
||||
</div>
|
||||
|
||||
<p class="blog-entry-content-body">
|
||||
{!! $entry['body'] !!}
|
||||
</p>
|
||||
|
||||
<div class="blog-entry-content-taglist">
|
||||
@foreach($entry['tags'] as $tag)
|
||||
<span class="blog-entry-content-taglist-item">
|
||||
{{ $tag }}
|
||||
</span>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -11,6 +11,7 @@
|
|||
<div class="nav-section-component-links" :class="{ open: openNav }">
|
||||
<div class="nav-section-component-links-wrapper">
|
||||
<a class="navlink" href="/"><span>Home</span></a>
|
||||
<a class="navlink" href="/blog"><span>Blog</span></a>
|
||||
<a class="navlink" href="/contact"><span>Contact</span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue