mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-10 09:52:51 +00:00
got angular routing working - starting on html components
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
//"encoding/json"
|
||||
"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// IndexGET displays the home page
|
||||
func NotFound404(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
|
||||
http.Redirect(w, r, "/404.html", 404)
|
||||
|
||||
fmt.Fprint(w, "test")
|
||||
}
|
||||
29
controller/api/testApi.go
Normal file
29
controller/api/testApi.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ApiCall struct {
|
||||
Fname string
|
||||
Lname string
|
||||
}
|
||||
|
||||
// Redirect to discord
|
||||
func TestApiCall(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
|
||||
s := new(ApiCall)
|
||||
|
||||
s.Fname = ps.ByName("fname")
|
||||
s.Lname = ps.ByName("lname")
|
||||
|
||||
response, _ := json.MarshalIndent(s, "", " ")
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
fmt.Fprint(w, string(response))
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
//"encoding/json"
|
||||
"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// IndexGET displays the home page
|
||||
func IndexGet(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
response := "{\"test\" : 123}"
|
||||
|
||||
fmt.Fprint(w, response)
|
||||
|
||||
}
|
||||
13
controller/redirect.go
Normal file
13
controller/redirect.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Redirect to discord
|
||||
func Discord(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
|
||||
http.Redirect(w, r, "https://discordapp.com/invite/0Z2tzxKECEj2BHwj", 301)
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
404: Page not found
|
||||
330
public/css/style.css
Normal file
330
public/css/style.css
Normal file
@@ -0,0 +1,330 @@
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00B7FF;
|
||||
}
|
||||
|
||||
.textCenter {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.resume{
|
||||
font-size: 12pt;
|
||||
font-weight: 400;
|
||||
}
|
||||
.header {
|
||||
height: 400px;
|
||||
background: url("/public/images/headerBackground.jpg") center no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.headerText{
|
||||
font-size: 80px;
|
||||
color: white;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.large-text{
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.centerDiv{
|
||||
position: relative;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
max-width: 500px;
|
||||
padding: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-signin .form-control {
|
||||
position: relative;
|
||||
height: auto;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.form-file {
|
||||
max-width: 500px;
|
||||
padding: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-file .form-control {
|
||||
position: relative;
|
||||
height: 34px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.colorRed {
|
||||
color: red;
|
||||
}
|
||||
.colorGreen {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.timeForm {
|
||||
width: 30%;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.aboutMeImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Override Bootstrap's default container.
|
||||
*/
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.container {
|
||||
width: 970px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Masthead for nav
|
||||
*/
|
||||
|
||||
.blog-masthead {
|
||||
background-color: #428bca;
|
||||
-webkit-box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
|
||||
box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
/* Nav links */
|
||||
.blog-nav-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
font-weight: 500;
|
||||
color: #cdddeb;
|
||||
}
|
||||
.blog-nav-item:hover,
|
||||
.blog-nav-item:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Active state gets a caret at the bottom */
|
||||
.blog-nav .active {
|
||||
color: #fff;
|
||||
}
|
||||
.blog-nav .active:after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: -5px;
|
||||
vertical-align: middle;
|
||||
content: " ";
|
||||
border-right: 5px solid transparent;
|
||||
border-bottom: 5px solid;
|
||||
border-left: 5px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Blog name and description
|
||||
*/
|
||||
|
||||
.blog-header {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.blog-title {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 0;
|
||||
font-size: 60px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.blog-description {
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main column and sidebar layout
|
||||
*/
|
||||
|
||||
.blog-main {
|
||||
font-size: 18px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Sidebar modules for boxing content */
|
||||
.sidebar-module {
|
||||
padding: 15px;
|
||||
margin: 0 -15px 15px;
|
||||
}
|
||||
.sidebar-module-inset {
|
||||
padding: 15px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.sidebar-module-inset p:last-child,
|
||||
.sidebar-module-inset ul:last-child,
|
||||
.sidebar-module-inset ol:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Pagination */
|
||||
.pager {
|
||||
margin-bottom: 60px;
|
||||
text-align: left;
|
||||
}
|
||||
.pager > li > a {
|
||||
width: 140px;
|
||||
padding: 10px 20px;
|
||||
text-align: center;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Blog posts
|
||||
*/
|
||||
|
||||
.blog-post {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.blog-post-title {
|
||||
margin-bottom: 5px;
|
||||
font-size: 40px;
|
||||
}
|
||||
.blog-post-meta {
|
||||
margin-bottom: 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Footer
|
||||
*/
|
||||
|
||||
.blog-footer {
|
||||
padding: 40px 0;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
background-color: #f9f9f9;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.blog-footer p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.lowerLeft{
|
||||
color: white;
|
||||
display: table-cell;
|
||||
vertical-align: bottom;
|
||||
height: 400px;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.colorWhite{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.mitchell-navbar{
|
||||
border-radius: 0 !important;
|
||||
background-color: #262626;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.gist {
|
||||
width:600px !important;
|
||||
}
|
||||
|
||||
.gist-file{
|
||||
|
||||
}
|
||||
|
||||
.gist-data{
|
||||
max-height: 500px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.chart-legend li span{
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba( 255, 255, 255, .8 )
|
||||
url('http://i.stack.imgur.com/FhHRx.gif')
|
||||
50% 50%
|
||||
no-repeat;
|
||||
}
|
||||
|
||||
/* When the body has the loading class, we turn
|
||||
the scrollbar off with overflow:hidden */
|
||||
body.loading {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Anytime the body has the loading class, our
|
||||
modal element will be visible */
|
||||
body.loading .modal {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-file input[type=file] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
font-size: 100px;
|
||||
text-align: right;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
background: white;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
background-color: white !important;
|
||||
cursor: text !important;
|
||||
}
|
||||
BIN
public/images/aboutme.jpg
Normal file
BIN
public/images/aboutme.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
BIN
public/images/headerBackground.jpg
Normal file
BIN
public/images/headerBackground.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/images/headerBackground1.jpg
Normal file
BIN
public/images/headerBackground1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 587 KiB |
BIN
public/images/sensors.png
Normal file
BIN
public/images/sensors.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
49
public/js/app.js
Normal file
49
public/js/app.js
Normal file
@@ -0,0 +1,49 @@
|
||||
var app = angular.module('app', ['ngRoute']);
|
||||
|
||||
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
|
||||
$locationProvider.html5Mode({
|
||||
enabled: true,
|
||||
requireBase: false
|
||||
});
|
||||
|
||||
$routeProvider.
|
||||
when('/', {
|
||||
templateUrl: '/public/view/index.html',
|
||||
controller: 'IndexController'
|
||||
}).
|
||||
when('/sensors', {
|
||||
templateUrl: '/public/view/404.html',
|
||||
controller: 'SensorsController'
|
||||
}).
|
||||
when('/post/:postName', {
|
||||
templateUrl: '/public/view/post.html',
|
||||
controller: 'PostController'
|
||||
}).
|
||||
when('/discord', {
|
||||
redirect: 'https://discordapp.com/invite/0Z2tzxKECEj2BHwj'
|
||||
}).
|
||||
otherwise({
|
||||
templateUrl: '/public/view/404.html'
|
||||
});
|
||||
}]);
|
||||
|
||||
app.controller('IndexController', function($scope) {
|
||||
|
||||
$scope.message = 'This is Add new order screen';
|
||||
|
||||
});
|
||||
|
||||
|
||||
app.controller('SensorsController', function($scope) {
|
||||
|
||||
$scope.message = 'This is Show orders screen';
|
||||
|
||||
});
|
||||
|
||||
|
||||
//handle each post page after individual posts are selected
|
||||
app.controller('PostController', function($scope, $route, $routeParams) {
|
||||
|
||||
$scope.post = "/public/posts/" + $routeParams.postName + ".html";
|
||||
|
||||
});
|
||||
55
public/posts/1-1-2016.html
Normal file
55
public/posts/1-1-2016.html
Normal file
@@ -0,0 +1,55 @@
|
||||
<div class="blog-post">
|
||||
<h2 id="title" class="blog-post-title">Temperature Sensor - Server Side</h2>
|
||||
|
||||
<p id="date" class="blog-post-meta">January 1, 2016 by Mitchell</p>
|
||||
|
||||
<p id="intro">The server side coding is a bit more complicated than programming the ESP8266 itself. I use a NoSQL database to store the information and some of the queries are complex and can be confusing to understand. I also make use of REST API's to send the data to the client side.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Storing Information</h3>
|
||||
|
||||
<p>For this project I am using MongoDB to store all of my information because it goes well with my server, which is coded in Node.js, but any database could be used. I also wanted to learn about NoSQL databases because I already have experience with SQL databases. Information on coding the ESP8266 can be found <a href="/?post=12-18-2015.html">here</a> in a previous post.
|
||||
</p>
|
||||
|
||||
<code>mitchellg.me/temperature?temperature=0&humidity=0&location=0&key=0</code>
|
||||
|
||||
<p>Above is the GET request that is sent to the server from the ESP8266. Data is tranferred through GET parameters. The key is an authentication code that I set to prevent unwanted HTTP requests. This is similar to an API key. Below is the code implemented to handle the HTTP request from the ESP8266.
|
||||
</p>
|
||||
|
||||
<script src="https://gist.github.com/mgerb42/4bedafa2bde264ee3135.js"></script>
|
||||
|
||||
<h3>Creating the REST API</h3>
|
||||
|
||||
<p>There are many ways that I could display the temperature information on a graph, but I was trying to come up with a quick and easy way that was also efficient. I also wanted reusability in case I wanted to add or change things down the road. I decided I was going to use <a href="http://www.chartjs.org/">Chart.js</a> because it is open source and free. These graphs are implemented on the front end using javascript. Because of this I needed to figure out a way to send the sensor data to the client side. I felt that the best way for me to do it would be creating a REST API. I plan on making another post in the future explaining all of my client side code along with how to use Chart.js.
|
||||
</p>
|
||||
|
||||
<p>Now that I know how I want to display my information I just need to think of what information I want to display. I thought it would be cool to display a few different graphs. As of right now I have one graph that displays data by the year and one that displays by each month. The maximum and minimum temperature of each day are displayed as well as the average humidity for that day. The user can also select which year or which month to display and the graph will adjust accordingly.
|
||||
</p>
|
||||
|
||||
<p>Now that I know what information I need I can start developing my REST API. I have a MongoDB collection called "temperature", which stores temperature, humidity, location, and time updated. Updated is a type of Date, which I will use in all of the queries to group by each day. To do the grouping in MongoDB I needed to use the <a href="https://docs.mongodb.org/v3.0/aggregation/">aggregation functionality</a> of MongoDB. Aggregation allows me to essentially perform queries on top of queries using the MongoDB "pipeline". This is similar to an SQL query when a selection is performed within a selection.
|
||||
</p>
|
||||
|
||||
<script src="https://gist.github.com/mgerb42/4879f4897f7e863e9003.js"></script>
|
||||
|
||||
<h3>Explanation of MongoDB Queries</h3>
|
||||
|
||||
<p>The first function takes in a location and year and returns maximum and minimum temperature readings as well as average humidity for each day in the selected year. The results are also returned sorted from newest to oldest.
|
||||
</p>
|
||||
|
||||
<p>In the first part of the aggregation pipeline, which is $project, I am just selecting the temperature, humidity, year, month, and day. This part is important because it allows me to pull the year, month, and day from the date that is stored in the database. This way I do not have to store each of these entries separately in the database.
|
||||
</p>
|
||||
|
||||
<p>This data is then passed to the next part of the aggregation pipeline. The $match pipeline stage selects out information from the collection which match with the selected year and location.
|
||||
</p>
|
||||
|
||||
<p>The $group aggregation operator is the stage in which I actually group the data by the location, year, month, and day. For each group I also take the max and min temperatures along with the average humidity by using the correct accumulator operators. Now that I have the appropriate information I need, I just use the $sort pipeline operator to sort the data based on time updated.
|
||||
</p>
|
||||
|
||||
<p>The function to display by month is the exact same, except I take in the month attribute and add it to the $match operator within the aggregation pipeline. Just like that the query is complete and all I need to do is send the response back to the client. Chart.js uses JSON format, which makes things extremely easy because MongoDB querie results are in JSON. I set the content type to JSON, and use JSON.stringify() to convert the JSON to a readable format for debugging purposes. An example API request can be tested out here.
|
||||
</p>
|
||||
|
||||
<p><a href="/api/sensorbylocation/year?location=Winona%20Apartment&year=2016">/api/sensorbylocation/year?location=Winona%20Apartment&year=2016</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
test
|
||||
23
public/view/404.html
Normal file
23
public/view/404.html
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<h1 class="text-center large-text">404</h1>
|
||||
<h4 class="text-center">This page may be in production, or it may not exist.</h4>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
25
public/view/index.html
Normal file
25
public/view/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-8 blog-main">
|
||||
|
||||
</div> <!-- new blog posts-->
|
||||
|
||||
<div class="col-sm-4 blog-sidebar">
|
||||
<h1 class="text-center">About Me</h1>
|
||||
<img class="aboutMeImage center img-rounded" src="/public/images/aboutme.jpg">
|
||||
|
||||
<br>
|
||||
|
||||
<div class="sidebar-module sidebar-module-inset">
|
||||
<p> I'm 22 years old and currently attending Winona State University as a Computer Science major.
|
||||
I am graduating in Spring of 2016 and plan to pursue a career in the field of software development.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
27
public/view/post.html
Normal file
27
public/view/post.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-8 blog-main">
|
||||
|
||||
<ng-include src="post"></ng-include>
|
||||
|
||||
</div> <!-- new blog posts-->
|
||||
|
||||
<div class="col-sm-4 blog-sidebar">
|
||||
<h1 class="text-center">About Me</h1>
|
||||
<img class="aboutMeImage center img-rounded" src="/public/images/aboutme.jpg">
|
||||
|
||||
<br>
|
||||
|
||||
<div class="sidebar-module sidebar-module-inset">
|
||||
<p> I'm 22 years old and currently attending Winona State University as a Computer Science major.
|
||||
I am graduating in Spring of 2016 and plan to pursue a career in the field of software development.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
100
public/view/template.html
Normal file
100
public/view/template.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>mitchel.io</title>
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="/public/css/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css">
|
||||
<link href='https://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
|
||||
|
||||
<style>
|
||||
[ng\:cloak], [ng-cloak], .ng-cloak {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body ng-app="app" ng-cloak>
|
||||
|
||||
<div class="header">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="lowerLeft">
|
||||
<h1 class="">mitchel.io</h1>
|
||||
<p class="">A site in which I share information about my personal projects.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<nav class="navbar mitchell-navbar" role="navigation">
|
||||
<div class="container">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="/">Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/sensors">Sensors</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/resume">Resume</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="mailto:mgerber11@winona.edu">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="/newpost">New Post</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!-- /.navbar-collapse -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<!-- dynamically load content into the page with angular (ng-view) -->
|
||||
<ng-view></ng-view>
|
||||
<!-- ------------------------------------------------------------- -->
|
||||
|
||||
|
||||
|
||||
<footer class="blog-footer">
|
||||
<p>Site created and managed by Mitchell Gerber</p>
|
||||
<span>©2015-2016</span>
|
||||
<br>
|
||||
<span>Glyphicons provided by</span><br>
|
||||
<a href="http://glyphicons.com/" target="_blank"><span>glyphicons.com</span></a>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/i18n/jquery-ui-i18n.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-resource.js"></script>
|
||||
<script src="/public/js/app.js"></script>
|
||||
|
||||
</html>
|
||||
@@ -1,24 +1,42 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
//"encoding/json"
|
||||
//"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
|
||||
"github.com/mgerb42/mywebsite/controller"
|
||||
"github.com/mgerb42/mywebsite/controller/api"
|
||||
)
|
||||
|
||||
func Routes() *httprouter.Router {
|
||||
|
||||
r := httprouter.New()
|
||||
|
||||
r.GET("/", controller.IndexGet)
|
||||
r.GET("/api/:fname/:lname", api.TestApiCall)
|
||||
|
||||
//set up public folder path
|
||||
r.ServeFiles("/public/*filepath", http.Dir("./public"))
|
||||
|
||||
//404 not found
|
||||
r.NotFound = http.NotFoundHandler()
|
||||
//route every invalid request to template file
|
||||
//routing is all handled on the client side with angular
|
||||
r.NotFound = http.HandlerFunc(fileHandler("./public/view/template.html"))
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
//route requests to static files
|
||||
func routerFileHandler(path string) httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
|
||||
http.ServeFile(w, r, path)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//function to serve files with standard net/http library
|
||||
func fileHandler(path string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.ServeFile(w, r, path)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
12
testing_files/404.go
Normal file
12
testing_files/404.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// IndexGET displays the home page
|
||||
func PageNotFound(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.ServeFile(w, r, "./public/404.html")
|
||||
|
||||
}
|
||||
77
testing_files/index.go
Normal file
77
testing_files/index.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
Location City
|
||||
Name string
|
||||
Age int
|
||||
Car []Car
|
||||
}
|
||||
|
||||
type City struct {
|
||||
Coords Coordinate
|
||||
Population int
|
||||
}
|
||||
|
||||
type Coordinate struct {
|
||||
Latitude int
|
||||
Longitude int
|
||||
}
|
||||
|
||||
type Car struct {
|
||||
Make string
|
||||
Year int
|
||||
}
|
||||
|
||||
// IndexGET displays the home page
|
||||
func IndexGet(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
|
||||
params := p.ByName("test")
|
||||
fmt.Println(params)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
js := Person{
|
||||
Location: City{
|
||||
Coords: Coordinate{
|
||||
Latitude: 23,
|
||||
Longitude: 32,
|
||||
},
|
||||
Population: 5000,
|
||||
},
|
||||
Name: "Mitchell",
|
||||
Age: 22,
|
||||
Car: []Car{
|
||||
Car{
|
||||
Make: "Mitz",
|
||||
Year: 2003,
|
||||
},
|
||||
Car{
|
||||
Make: "Honda",
|
||||
Year: 2016,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
b, err := json.MarshalIndent(js, "", " ")
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error)
|
||||
}
|
||||
|
||||
s := string(b)
|
||||
|
||||
fmt.Fprint(w, s)
|
||||
|
||||
}
|
||||
|
||||
func Api(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
param := p.ByName("name")
|
||||
fmt.Fprint(w, param)
|
||||
}
|
||||
13
testing_files/redirect.go
Normal file
13
testing_files/redirect.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Redirect to discord
|
||||
func Discord(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
|
||||
http.Redirect(w, r, "https://discordapp.com/invite/0Z2tzxKECEj2BHwj", 301)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user