homepage redesign

This commit is contained in:
Lee Lawlor
2014-05-08 20:01:41 -04:00
parent e5570ec3af
commit ac83280b68
57 changed files with 569 additions and 328 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -0,0 +1,25 @@
// when the dom is ready
$(document).ready(function() {
// if the cheerlights row exists
if ($('#cheerlights_row').length > 0) {
// get the initial update
cheerlightsUpdate();
// check for new updates
setInterval('cheerlightsUpdate()', 15000);
}
});
// cheerlights update
function cheerlightsUpdate() {
// get the data with a webservice call
$.getJSON('https://api.thingspeak.com/channels/1417/feed/last.json', function(data) {
// if the field1 has data update the page
if (data.field1) {
if (data.field1 == "warmwhite") {data.field1 = "oldlace"}
$("#cheerlights_row").css("background-color", data.field1);
}
});
}

View File

@ -20,5 +20,10 @@ $(document).ready(function() {
$('#talkback_command_add_form').removeClass('hide');
});
// toggle contact form
$('#contact_link').click(function() {
$('#contact_form').toggle();
});
});

View File

@ -1,6 +1,4 @@
/*
*= require ./bootstrap_custom.min.css
*= require ./bootstrap_overrides.css
*= require ./jquery-ui-1.8.24.custom.css
*= require ./custom.css
*= require ./status.css

View File

@ -1,14 +1,29 @@
/* bootstrap overrides */
code { word-wrap: break-word; white-space: normal; }
.navbar-collapse { max-height: 350px; }
.breadcrumb { margin-top: 10px; margin-bottom: 20px; } /* margins to make sure breadcrumb and h4.breadcrumb line up properly */
.table td { word-break: break-word; }
/* homepage */
#home-motto { font-size: 2em; padding-top: 100px; }
#home-motto h1 { font-size: 2em; color: #fff; }
#home-top { height: 500px; width: 100%; background: url('<%= asset_path("thingspeak_stars_bg.jpg") %>') no-repeat; background-size: 100% 500px; text-align: center; color: #fff; }
#home-top a { color: #fff; }
.panel-home { min-height: 180px; }
/* misc */
body { padding-top: 70px; }
#cheerlights_row { text-align: center; height: 180px; }
#cheerlights_row img { margin-top: 40px; }
.break-word { word-break: break-word; }
.col-pad { padding: 0 15px; }
.dismiss { float: right; cursor: pointer; position: relative; top: -12px; left: 7px; }
/* contact form */
#contact_form { display: none; }
#contact_link { cursor: pointer; }
#contact_link:hover { text-decoration: none; }
/* multiline forms */
.form-horizontal .multiline-label { margin-top: -10px; }
@ -305,11 +320,6 @@ input#upload_csv { padding-top:5px;margin:20px 0;}
/* form styling */
input.video_narrow {width:100px; }
/* home page */
#feature_signup {}
#feature_signup a {border-bottom: 3px solid #d62020; text-decoration: none; font-weight: bold;}
#feature_signup a:hover {text-decoration: none;}
/* jQuery Nav */
#nav { list-style: none; padding:0 10px 0 92px; margin: 0;}

View File

@ -1,9 +1,10 @@
class PagesController < ApplicationController
layout 'application', :except => [:social_home]
layout 'application', :except => [:home, :social_home]
def home
@menu = 'home'
@title = 'Internet of Things'
render layout: 'home'
end
def social_home; ; end
@ -19,5 +20,22 @@ class PagesController < ApplicationController
def headers
end
# post contact email
def contact_us
# if no email address
if params[:email].blank? || params[:email].index('@').blank?
flash[:alert] = t(:contact_us_no_email)
# if no message
elsif params[:message].blank?
flash[:alert] = t(:contact_us_no_message)
# else send email
else
Mailer.contact_us(params[:email], params[:message]).deliver
flash[:notice] = t(:contact_us_success)
end
redirect_to root_path
end
end

View File

@ -6,7 +6,7 @@ module PagesHelper
# get the blog data
blog_url = "http://community.thingspeak.com"
doc = Nokogiri::HTML(open(blog_url, "User-Agent" => "Ruby/#{RUBY_VERSION}").read)
# parse out the html we need
doc.css("img").remove
doc.css("script").remove
@ -16,7 +16,7 @@ module PagesHelper
if (i < 3)
blog += d.css("h2").to_s
blog += d.css("div.entry").to_s
blog += "<br /><br />"
blog += "<hr>" if i != 2
end
end
end
@ -26,3 +26,4 @@ module PagesHelper
blog
end
end

View File

@ -8,4 +8,14 @@ class Mailer < ActionMailer::Base
:subject => t(:password_reset_subject))
end
def contact_us(from_email, message)
mail(to: SUPPORT_EMAIL,
from: from_email,
reply_to: from_email,
body: message,
content_type: "text/html",
subject: "Contact Us Form")
end
end

View File

@ -0,0 +1,7 @@
<% if notice.present? %>
<p class="flash alert alert-success"><%= notice %><span class="dismiss">X</span></p>
<% end %>
<% if alert.present? %>
<p class="flash alert alert-danger"><%= alert %><span class="dismiss">X</span></p>
<% end %>

View File

@ -1,71 +1,20 @@
<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>
<%= link_to root_path do %>
<%= image_tag 'thingspeak_logo.png', :size => '190x50', :style => 'padding: 0 8px;' %>
<% end %>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<head>
<title><%= @title.nil? ? (@menu.nil? ? 'ThingSpeak' : @menu.capitalize + ' - ThingSpeak') : @title + ' - ThingSpeak' %></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/cerulean/bootstrap.min.css" />
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" media="screen" rel="stylesheet" />
<%= stylesheet_link_tag 'application' %>
<% if current_user %>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<%= javascript_include_tag 'application' %>
<li class="<%= "active " if @menu == 'channels' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:channels)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><%= link_to t(:channels_my), channels_path %></li>
<li><%= link_to t(:watched_channels), watched_channels_path %></li>
<li><%= link_to t(:channels_public), public_channels_path %></li>
</ul>
</li>
<li <%= "class=active" if @menu == 'plugins' %>><%= link_to t(:plugins), plugins_path %></li>
<li class="<%= "active " if @menu == 'account' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:account)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><%= link_to t(:myaccount), account_path %></li>
<li><%= link_to t(:account_edit), edit_account_path %></li>
<li><%= link_to t(:public_profile), user_profile_path(current_user.login) %></li>
<li><%= link_to t(:profile_edit), edit_profile_path %></li>
</ul>
</li>
<% if current_admin_user.present? %>
<li><%= link_to t(:admin), "/admin" %></li>
<% end %>
<%= csrf_meta_tag %>
<% if Rails.env == 'production' %>
<%= render 'layouts/ga' %>
<% end %>
<% else %>
<li <%= "class=active" if @menu == 'channels' %>><%= link_to t(:channels), public_channels_path %></li>
<li <%= "class=active" if @menu == 'features' %>><%= link_to t(:features), features_pages_path %></li>
<% end %>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="<%= "active " if @menu == 'support' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:support)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/docs"><%= t(:documentation) %></a></li>
<li><a href="http://community.thingspeak.com/tutorials/"><%= t(:tutorials) %></a></li>
<li><a href="http://community.thingspeak.com/forum/"><%= t(:forum) %></a></li>
</ul>
</li>
<li><a href="http://community.thingspeak.com/"><%= t(:blog)%></a></li>
<% if current_user %>
<li><%= link_to t(:signout), logout_path %></li>
<% else %>
<li><%= link_to t(:signin), login_path %></li>
<li><%= link_to t(:signup), new_user_registration_path %></li>
<% end %>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<%= yield :head %>
</head>

View File

@ -0,0 +1,70 @@
<div class="navbar navbar-inverse 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>
<%= link_to root_path do %>
<%= image_tag 'thingspeak_logo_white.png', :size => '188x35', :style => 'padding: 0 8px; margin-top: 7px;' %>
<% end %>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<% if current_user %>
<li class="<%= "active " if @menu == 'channels' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:channels)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><%= link_to t(:channels_my), channels_path %></li>
<li><%= link_to t(:watched_channels), watched_channels_path %></li>
<li><%= link_to t(:channels_public), public_channels_path %></li>
</ul>
</li>
<li <%= "class=active" if @menu == 'plugins' %>><%= link_to t(:plugins), plugins_path %></li>
<li class="<%= "active " if @menu == 'account' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:account)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><%= link_to t(:myaccount), account_path %></li>
<li><%= link_to t(:account_edit), edit_account_path %></li>
<li><%= link_to t(:public_profile), user_profile_path(current_user.login) %></li>
<li><%= link_to t(:profile_edit), edit_profile_path %></li>
</ul>
</li>
<% if current_admin_user.present? %>
<li><%= link_to t(:admin), "/admin" %></li>
<% end %>
<% else %>
<li <%= "class=active" if @menu == 'channels' %>><%= link_to t(:channels), public_channels_path %></li>
<% end %>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="<%= "active " if @menu == 'support' %>dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%=t(:support)%> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/docs"><%= t(:documentation) %></a></li>
<li><a href="/docs/tutorials/"><%= t(:tutorials) %></a></li>
<li><a href="http://community.thingspeak.com/forum/"><%= t(:forum) %></a></li>
</ul>
</li>
<li><a href="http://community.thingspeak.com/"><%= t(:blog)%></a></li>
<% if current_user %>
<li><%= link_to t(:signout), logout_path %></li>
<% else %>
<li><%= link_to t(:signin), login_path %></li>
<li><%= link_to t(:signup), new_user_registration_path %></li>
<% end %>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>

View File

@ -1,34 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title><%= @title.nil? ? (@menu.nil? ? 'ThingSpeak' : @menu.capitalize + ' - ThingSpeak') : @title + ' - ThingSpeak' %></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<%= stylesheet_link_tag 'application' %>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tag %>
<% if Rails.env == 'production' %>
<%= render 'layouts/ga' %>
<% end %>
<%= yield :head %>
</head>
<%= render 'layouts/header' %>
<body>
<div id="wrap">
<%= render 'layouts/header' %>
<%= render 'layouts/nav' %>
<div class="container">
<% if notice.present? %>
<p class="flash alert alert-success"><%= notice %><span class="dismiss">X</span></p>
<% end %>
<% if alert.present? %>
<p class="flash alert alert-danger"><%= alert %><span class="dismiss">X</span></p>
<% end %>
<%= render 'layouts/flash' %>
<%= yield %>
</div>
</div>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<%= render 'layouts/header' %>
<body style='padding-top: 50px;'>
<%= render 'layouts/nav' %>
<%= yield %>
<%= render 'layouts/footer' %>
</body>
</html>

View File

@ -0,0 +1,17 @@
<%= form_tag({:controller => 'pages', :action => 'contact_us', :method => :post}, :class => 'form-horizontal') do %>
<div class="form-group">
<label class="col-sm-4 col-xs-3 control-label"><%= t(:email_address).titleize %></label>
<div class="col-sm-4 col-xs-9"><%= text_field_tag :email, (current_user.present? ? current_user.email : nil), :class => 'form-control' %></div>
</div>
<div class="form-group">
<label class="col-sm-4 col-xs-3 control-label"><%= t(:message).capitalize %></label>
<div class="col-sm-4 col-xs-9"><%= text_area_tag :message, nil, :class => 'form-control', :rows => 8 %></div>
</div>
<div class="form-group">
<label class="col-sm-4 col-xs-3 control-label"></label>
<div class="col-sm-4 col-xs-9"><p class="form-control-static"><%= submit_tag t(:submit), :class => 'btn btn-primary' %></p></div>
</div>
<% end %>

View File

@ -1,230 +1,129 @@
<script type="text/javascript">
// users timezone offset
var myOffset = new Date().getTimezoneOffset();
<div id="home-top">
// converts date format from JSON
function getChartDate(d) {
// get the data using javascript's date object (year, month, day, hour, minute, second)
// months in javascript start at 0, so remember to subtract 1 when specifying the month
// offset in minutes is converted to milliseconds and subtracted so that chart's x-axis is correct
return Date.UTC(d.substring(0,4), d.substring(5,7)-1, d.substring(8,10), d.substring(11,13), d.substring(14,16), d.substring(17,19)) - (myOffset * 60000);
}
$(document).ready(function() {
// blank array for holding chart data
var chartData = [];
// variable for the date string
var d;
// variable for the data point
var p;
// variable for the local date in milliseconds
var localDate;
// get the data with a webservice call
$.getJSON('https://api.thingspeak.com/channels/9/field/1.json?callback=?&amp;results=15&amp;offset=0', function(data) {
// if no access
if (data == '-1') {
$('#chart-container').append('This channel is not public. To embed charts, the channel must be public or a read key must be specified.');
}
// iterate through each feed
$.each(data.feeds, function() {
p = this.field1;
// if a numerical value exists add it
if (!isNaN(parseInt(p))) {
chartData.push([getChartDate(this.created_at), parseFloat(p)]);
}
});
// specify the chart options
var chartOptions = {
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'line',
backgroundColor: '#fff',
events: {
load: function() {
// push data every 15 seconds
setInterval(function() {
// get the data with a webservice call
$.getJSON('https://api.thingspeak.com/channels/9/feed/last.json?callback=?&amp;offset=0', function(data) {
p = data.field1;
d = getChartDate(data.created_at);
last_date = dynamicChart.series[0].data[dynamicChart.series[0].data.length-1].x;
// if a numerical value exists and it is a new date, add it
if (!isNaN(parseInt(p)) && (d != last_date)) {
dynamicChart.series[0].addPoint([d, parseFloat(p)], true, true);
}
});
}, 15000);
}
}
},
title: {
text: ''
},
plotOptions: {
line: {
color: '#d62020'
},
bar: {
color: '#d62020'
},
column: {
color: '#d62020'
},
series: {
marker: {
radius: 3
},
animation: true
}
},
tooltip: {
// reformat the tooltips so that local times are displayed
formatter: function() {
var d = new Date(this.x + (myOffset*60000));
return this.series.name + ':<b>' + this.y + '</b><br/>' + d.toDateString() + '<br/>' + d.toTimeString().replace(/\(.*\)/, "");
}
},
xAxis: {
type: 'datetime',
title: {
text: ''
}
},
yAxis: {
title: {
text: ''
}
},
exporting: {
enabled: false
},
legend: {
enabled: false
},
series: [{
name: data.channel.field1
}]
};
// add the data to the chart
chartOptions.series[0].data = chartData;
// set chart labels here so that decoding occurs properly
chartOptions.title.text = 'Dynamic Light Levels';
chartOptions.xAxis.title.text = 'Time';
chartOptions.yAxis.title.text = data.channel.field1;
// draw the chart
var dynamicChart = new Highcharts.Chart(chartOptions);
});
});
</script>
<div class="row">
<div class="text-center">
<%= image_tag 'front.png', :size => '854x144' %>
<div id="home-motto">
<h1><%= t(:home_motto) %></h1>
<%= t(:home_tagline) %>
</div>
<br><br>
<div>
<%= link_to t(:get_started), new_user_registration_path, :class => 'btn btn-danger btn-lg' %>
<br><br>
<a href="/docs" target="_blank"><%= t(:documentation) %></a>
&nbsp; | &nbsp;
<a href="http://community.thingspeak.com/forum/" target="_blank"><%=t(:support)%></a>
&nbsp; | &nbsp;
<a href="https://github.com/iobridge/thingspeak" target="_blank">GitHub</a>
</div>
</div>
<br><br><br>
<br><br>
<div class="row">
<div class="col-sm-6">
<div id="chart-container" class="center-block" style="width: 500px; height: 260px; padding-left: 20px;"></div>
</div>
<div class="col-sm-6">
<div style="margin-top: 55px;" class="text-center"><a href="http://community.thingspeak.com/tutorials/netduino/create-your-own-web-of-things-using-the-netduino-plus-and-thingspeak/"><%= image_tag 'my_house_status_update.png' %></a></div>
</div>
</div>
<div class="container">
<br><br><br>
<div class="row">
<div class="row">
<div class="col-sm-4">
<h4 class="breadcrumb">Features</h4>
<p>
<ul>
<li>Open Source API</li>
<li>Real-time data collection</li>
<li>Data processing</li>
<li>Data visualizations</li>
<li>Location-awareness</li>
<li>Status context</li>
<li>Application infrastructure</li>
<li>Twitter proxy</li>
<li>Apps</li>
<li>Plugins</li>
<li><%= link_to '... more', features_pages_path %></li>
</ul>
</p>
</div>
<div class="col-sm-4">
<h4 class="breadcrumb">Applications</h4>
<p>
<ul>
<li>Sensor monitoring</li>
<li>Energy monitoring</li>
<li>Connecting devices and systems</li>
<li>Geo location tracking</li>
<li>Interfacing with social networks</li>
<li>RFID transactions</li>
</ul>
</p>
<h4 class="breadcrumb">Who Uses ThingSpeak</h4>
<p>
<ul>
<li>Application developers</li>
<li>Product integrators</li>
<li>Web designers</li>
</ul>
</p>
</div>
<div class="col-sm-4">
<h4 class="breadcrumb">Get Started</h4>
<div class="col-pad">
If you are ready to get started, <span id="feature_signup"> <%= link_to t(:signup), new_account_path %></span> for a free user account.
<div class="col-sm-4">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-list fa-fw fa-lg"></i>
ThingSpeak Features
</h3>
</div>
<div class="panel-body panel-home">
<ul>
<li>Open API</li>
<li>Real-time data collection</li>
<li>Geolocation data</li>
<li>Data processing</li>
<li>Data visualizations</li>
<li>Device status messages</li>
<li>Plugins</li>
</ul>
</div>
</div>
<h4 class="breadcrumb">Connect</h4>
<p>
<ul>
<li><a href="http://www.twitter.com/thingspeak" title="Follow ThingSpeak on Twitter">Twitter</a></li>
<li><a href="https://github.com/iobridge/ThingSpeak" title="Open Source Internet of Things Project on GitHub">GitHub</a></li>
<li><a href="http://community.thingspeak.com" title="Join the ThingSpeak Community">ThingSpeak Community</a></li>
<li><a href="/docs" title="ThingSpeak API and Apps Documentation">Documentation</a> and <a href="http://community.thingspeak.com/tutorials" title="ThingSpeak Tutorials">Tutorials</a></li>
<li><a href="mailto:support@thingspeak.com" title="Contact ThingSpeak">Questions</a></li>
</ul>
</p>
</div>
<div class="col-sm-4">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-gears fa-fw fa-lg"></i>
Integrate With Anything
</h3>
</div>
<div class="panel-body panel-home">
<ul>
<li>Arduino</li>
<li>Raspberry Pi</li>
<li>ioBridge / RealTime.io</li>
<li>Electric Imp</li>
<li>Mobile / Web Applications</li>
<li>Social Networks</li>
<li>Data Analytics</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-comments fa-fw fa-lg"></i>
Connect With Us
</h3>
</div>
<div class="panel-body panel-home">
<ul>
<li><a href="https://github.com/iobridge/ThingSpeak" title="Open Source Internet of Things Project on GitHub">GitHub</a></li>
<li><a href="http://www.twitter.com/thingspeak" title="Follow ThingSpeak on Twitter">Twitter</a></li>
<li><a href="http://community.thingspeak.com/" title="ThingSpeak IoT Blog">Blog</a></li>
<li><a href="http://community.thingspeak.com/forum/" title="Join the ThingSpeak Forum">Forum</a></li>
<li><a href="/docs" title="ThingSpeak API and Apps Documentation">Documentation</a></li>
<li><a href="/docs/tutorials" title="ThingSpeak Tutorials">Tutorials</a></li>
<li><a href="mailto:support@thingspeak.com" title="Contact ThingSpeak">Questions</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<br><br>
<br><br><br>
<div class="row">
<div class="col-sm-offset-2 col-sm-8 col-xs-12">
<div class="center-block" style="max-width: 600px;">
<h4><a href="http://community.thingspeak.com/" title="ThingSpeak Community, Blog, and Forum">latest news<a> <a href="http://feeds.feedburner.com/internetofthings/" title="ThingSpeak RSS Feed"><%= image_tag 'icon_rss.gif' %></a></h4>
<div class="jumbotron">
<h1>Get Started</h1>
<p>If you are ready to build your Internet of Things, <%= link_to t(:signup), new_user_registration_path, :class => 'btn btn-primary btn-sm' %> for a free developer account.</p>
<p>
<a href="/docs" target="_blank" class="btn btn-info btn-lg">Learn More</a>
<a id="contact_link" class="btn btn-success btn-lg"><%= t(:contact_us) %></a>
</p>
<div id="contact_form">
<br>
<%= render :partial => 'pages/contact_form' %>
</div>
</div>
<br><br>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
<a href="http://community.thingspeak.com/" title="ThingSpeak Community, Blog, and Forum">Latest News<a> <a href="http://feeds.feedburner.com/internetofthings/" title="ThingSpeak RSS Feed"><%= image_tag 'icon_rss.gif' %></a>
</h3>
</div>
<div class="panel-body">
<% cache("blog-posts-on-homepage", :expires_in => 10.minutes) do %>
<%= raw blog_entries %>
<% end %>
</div>
</div>
<br>
</div>