Consolidated default and nojs versions of site
Removed old nojs specific templates and updated "templates/default.html" and "templates/partials/nav.html" to support nojs. All pages now use relativized urls. Navigation pages (including blog paginated pages) are generated to "/" instead of "/pages/". Site now works when javascript is disabled. Unfortunately, it no longer works when javascript is enabled. This is due to the client side router but needs to be debugged further. Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
parent
df6d5f0e68
commit
e634f0fbe4
61
TODO.org
61
TODO.org
@ -1,26 +1,13 @@
|
||||
* rm-js-req TODOs
|
||||
|
||||
** Goals
|
||||
*** TODO Remove the javascipt requirement (so that all urls can be viewed without javascript)
|
||||
*** TODO Only generate one version of the site
|
||||
*** TODO Have SPA functionality when javascript is enabled
|
||||
*** Complete
|
||||
**** DONE Remove the javascipt requirement (so that all urls can be viewed without javascript)
|
||||
CLOSED: [2015-08-10 Mon 22:57]
|
||||
**** DONE Only generate one version of the site
|
||||
CLOSED: [2015-08-10 Mon 22:57]
|
||||
|
||||
** Implementation
|
||||
In order to implement this, a reasonable size refactor needs to take place. Below is a list
|
||||
of things to be completed in order to successfully achieve the aforementioned goals.
|
||||
|
||||
*** TODO Generate nav with href pointing to normal urls, not virtual ones
|
||||
(Eg. /pages/blog.html instead of #/blog.html)
|
||||
*** TODO Modify URLs using javascript once page is loaded
|
||||
If it is indeed enabled then the user can benefit from the SPA functionality of the site.
|
||||
Otherwise they will be able to browse the site using the original, unmodified links. This is
|
||||
similar to how the link withing the page-content div work currently, and mainly would have to
|
||||
be adapted for the navigation.
|
||||
*** TODO Generate pages/* to /
|
||||
Instead of having the default version
|
||||
*** TODO Generate complete pages (no snippets)
|
||||
The enhanced javascipt additions to the site will then have to extract the page-content div
|
||||
before loading it into the page.
|
||||
|
||||
** Benefits
|
||||
This refactor will have a couple added benefits. Namely:
|
||||
@ -30,3 +17,41 @@
|
||||
links to the posts are to the snippets instead of the virtual address (Eg.
|
||||
/posts/some-post.html instead of /#/posts/some-post.html).
|
||||
- Having two files for every post is bad for search engines (SEO).
|
||||
|
||||
** Implementation
|
||||
In order to implement this, a reasonable size refactor needs to take place. Below is a list
|
||||
of things to be completed in order to successfully achieve the aforementioned goals.
|
||||
|
||||
*** TODO Modify nav URLs using javascript once page is loaded
|
||||
If it is indeed enabled then the user can benefit from the SPA functionality of the site.
|
||||
Otherwise they will be able to browse the site using the original, unmodified links. This is
|
||||
similar to how the link withing the page-content div work currently, and mainly would have to
|
||||
be adapted for the navigation.
|
||||
|
||||
*** TODO Fix issue with tag and pagination urls <<page loading issue>>
|
||||
All URLs are required to work without javascript. Thus there can't be any tricks employed
|
||||
in javascript to modify urls (the js router rewriting). Currently this happens with the
|
||||
|
||||
- "/blog.html" to "/blog1.html"
|
||||
- "/tags/general.html" to "/tags/general1.html"
|
||||
- etc..
|
||||
|
||||
Currently URLs to paginated pages (which includes the blog and tag pages) are broken. They
|
||||
generate "/tags/*.html" instead of "/tags/*1.html".
|
||||
|
||||
*** TODO Fix ajax page loading
|
||||
Pages don't load properly when javascript is enabled. This likely is having an effect on
|
||||
this [[page loading issue][issue]] as well. More debugging is required.
|
||||
|
||||
*** Complete
|
||||
**** DONE Generate nav with href pointing to normal urls, not virtual ones
|
||||
CLOSED: [2015-08-10 Mon 22:55]
|
||||
(Eg. /pages/blog.html instead of #/blog.html)
|
||||
Note: must be relative urls (via relativizeUrls)
|
||||
**** DONE Generate pages/* to /
|
||||
CLOSED: [2015-08-10 Mon 22:56]
|
||||
Instead of having the default version
|
||||
**** DONE Generate complete pages (no snippets)
|
||||
CLOSED: [2015-08-10 Mon 22:57]
|
||||
The enhanced javascipt additions to the site will then have to extract the page-content div
|
||||
before loading it into the page.
|
||||
|
244
js/default.js
244
js/default.js
@ -111,12 +111,12 @@ _paq.push(['enableLinkTracking']);
|
||||
acceptUrls: /.*/,
|
||||
rewriteGetUrl: function (url) {
|
||||
if (url === "/") {
|
||||
url = "/home.html";
|
||||
url = "/index.html";
|
||||
}
|
||||
return "pages" + url;
|
||||
},
|
||||
rewriteVirtualUrl: function (url) {
|
||||
if (url === "/home.html") {
|
||||
if (url === "/index.html") {
|
||||
url = "/";
|
||||
}
|
||||
return url;
|
||||
@ -124,7 +124,7 @@ _paq.push(['enableLinkTracking']);
|
||||
ajaxCallbacks: {
|
||||
beforeSend: function (url, virt_url) {
|
||||
if (virt_url === "/") {
|
||||
virt_url = "/home.html";
|
||||
virt_url = "/index.html";
|
||||
}
|
||||
|
||||
// Initially set the active menuitem in the nav
|
||||
@ -176,144 +176,140 @@ _paq.push(['enableLinkTracking']);
|
||||
return spec;
|
||||
}()),
|
||||
|
||||
page = (function () {
|
||||
// var pageId = '#page-content', navId = '#nav';
|
||||
page = (function () {
|
||||
// var pageId = '#page-content', navId = '#nav';
|
||||
|
||||
function loadPageContent(page_href, virt_href, handlerCallback) {
|
||||
// Track page view with piwik
|
||||
_paq.push(['setDocumentTitle', document.domain + '/' + virt_href]);
|
||||
_paq.push(['trackPageView']);
|
||||
function loadPageContent(page_href, virt_href, handlerCallback) {
|
||||
// Track page view with piwik
|
||||
_paq.push(['setDocumentTitle', document.domain + '/' + virt_href]);
|
||||
_paq.push(['trackPageView']);
|
||||
|
||||
$.ajax({
|
||||
url: page_href,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
beforeSend: function (xhr, settings) {
|
||||
// Remove loading error from page-content
|
||||
$('#page-content').removeClass('loading-error');
|
||||
// Remove loading error from page-content
|
||||
$('#page-content').removeClass('loading-error');
|
||||
|
||||
// Add .loading to #page-content and #nav to facilitate a loading animation
|
||||
$('#page-content, #nav').removeClass('loading-done').addClass('loading');
|
||||
// Add .loading to #page-content and #nav to facilitate a loading animation
|
||||
$('#page-content, #nav').removeClass('loading-done').addClass('loading');
|
||||
|
||||
// Run current handlers onSuccess callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
|
||||
handlerCallback.beforeSend(page_href, virt_href);
|
||||
}
|
||||
// Run current handlers onSuccess callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
|
||||
handlerCallback.beforeSend(page_href, virt_href);
|
||||
}
|
||||
|
||||
console.log('beforeSend a.menuitem');
|
||||
},
|
||||
success: function (dta) {
|
||||
// Remove the initial loading gif (if its there)
|
||||
$('#page-content').removeClass('init');
|
||||
console.log('beforeSend a.menuitem');
|
||||
|
||||
// Remove any status message errors or successes
|
||||
$('#status').slideUp('normal', function () {
|
||||
$('#status').removeClass('error').removeClass('success').children('p.message').remove();
|
||||
});
|
||||
|
||||
// Stop animations in the nav and page-content and scroll to the top of the page in a set amount of time
|
||||
setTimeout(function () {
|
||||
// Replace old page-content with new page-content
|
||||
$('#page-content').html(dta);
|
||||
|
||||
// Stop page loading
|
||||
$('#page-content, #nav').removeClass('loading');
|
||||
|
||||
// Reload any new maths using MathJax
|
||||
$('#page-content .math').each(function (math_elem) {
|
||||
mj.Hub.Queue(["Typeset", mj.Hub, math_elem[0]]);
|
||||
});
|
||||
|
||||
// Rewrite new URLs within new content inserted into #page-content
|
||||
$('#page-content a').each(function (i) {
|
||||
var href = $(this).attr('href'),
|
||||
external_url_regexp = /https?:\/\/.*/,
|
||||
mailto_regexp = /mailto:.*/,
|
||||
files_regexp = /files\/.*/,
|
||||
images_regexp = /images\/.*/;
|
||||
|
||||
if (!(external_url_regexp.test(href) || mailto_regexp.test(href) || files_regexp.test(href) || images_regexp.test(href))) {
|
||||
$(this).attr('href', "/#" + href);
|
||||
}
|
||||
});
|
||||
|
||||
// Add fullscreen functionality to inline-images and figures
|
||||
$('article.post p > img').click(function () {
|
||||
$(this).get(0).toggleFullScreen();
|
||||
});
|
||||
$('figure').click(function () {
|
||||
$(this).children('img').get(0).toggleFullScreen();
|
||||
});
|
||||
|
||||
// Run current handles onSuccess callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('onSuccess') && typeof handlerCallback.onSuccess === 'function') {
|
||||
handlerCallback.onSuccess();
|
||||
}
|
||||
|
||||
// Scroll to top of the page
|
||||
if ($('body').scrollTop() > $('#nav').offset().top - 15) {
|
||||
$('html, body').animate({
|
||||
scrollTop: $('#nav').offset().top - 15
|
||||
}, 'fast');
|
||||
}
|
||||
}, 250);
|
||||
},
|
||||
error: function (xhr, status) {
|
||||
/* Remove .loading from #page-content and #nav to stop the loading
|
||||
* animation. Then add .loading-error to #page-content if its the sites
|
||||
* first load (#page-content has class .init). Finally, display an error
|
||||
* message in #status.
|
||||
*/
|
||||
$('#page-content, #nav').removeClass('loading');
|
||||
if ($('#page-content.init')[0]) {
|
||||
// TODO: instead of immediately displaying error, check if the content is stored in local storage
|
||||
$('#page-content').addClass('loading-error').html('<p class="container border-box">Error initially loading blog.rekahsoft.ca. Check the url! Given "' + page_href + '"</p>');
|
||||
} else if ($('#status.error')[0]) {
|
||||
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
|
||||
} else {
|
||||
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
|
||||
$('#status').addClass('error').slideDown();
|
||||
}
|
||||
|
||||
// Run current handles onError callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('onError') && typeof handlerCallback.onError === 'function') {
|
||||
handlerCallback.onError();
|
||||
}
|
||||
$('#page-content').load(page_href + ' #page-content', function (dta, status, xhr) {
|
||||
if (status === "error") {
|
||||
/* Remove .loading from #page-content and #nav to stop the loading
|
||||
* animation. Then add .loading-error to #page-content if its the sites
|
||||
* first load (#page-content has class .init). Finally, display an error
|
||||
* message in #status.
|
||||
*/
|
||||
$('#page-content, #nav').removeClass('loading');
|
||||
if ($('#page-content.init')[0]) {
|
||||
// TODO: instead of immediately displaying error, check if the content is stored in local storage
|
||||
$('#page-content').addClass('loading-error').html('<p class="container border-box">Error initially loading blog.rekahsoft.ca. Check the url! Given "' + page_href + '"</p>');
|
||||
} else if ($('#status.error')[0]) {
|
||||
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
|
||||
} else {
|
||||
$('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
|
||||
$('#status').addClass('error').slideDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init(router) {
|
||||
router.setCallback(loadPageContent);
|
||||
// Run current handles onError callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('onError') && typeof handlerCallback.onError === 'function') {
|
||||
handlerCallback.onError();
|
||||
}
|
||||
} else {
|
||||
// Remove the initial loading gif (if its there)
|
||||
$('#page-content').removeClass('init');
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#nav-menu a.menuitem').click(function () {
|
||||
$(this).closest('ul').find('li.active').removeClass('active');
|
||||
$(this).closest('li').addClass('active');
|
||||
//$('.navbar-collapse').collapse('hide');
|
||||
// Remove any status message errors or successes
|
||||
$('#status').slideUp('normal', function () {
|
||||
$('#status').removeClass('error').removeClass('success').children('p.message').remove();
|
||||
});
|
||||
|
||||
$('#status a.close-button').click(function () {
|
||||
$(this).parent().slideUp(function () {
|
||||
$(this).removeClass('error').removeClass('success');
|
||||
$(this).children('p.message').remove();
|
||||
// Stop animations in the nav and page-content and scroll to the top of the page in a set amount of time
|
||||
setTimeout(function () {
|
||||
// Replace old page-content with new page-content
|
||||
$('#page-content').html(dta);
|
||||
|
||||
// Stop page loading
|
||||
$('#page-content, #nav').removeClass('loading');
|
||||
|
||||
// Reload any new maths using MathJax
|
||||
$('#page-content .math').each(function (math_elem) {
|
||||
mj.Hub.Queue(["Typeset", mj.Hub, math_elem[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
// Callback for when the inital page has completely loaded (including images, etc..)
|
||||
$.address.change(function (event) {
|
||||
console.log("Change " + event.value);
|
||||
router.runRouter(event.value);
|
||||
// Rewrite new URLs within new content inserted into #page-content
|
||||
$('#page-content a').each(function (i) {
|
||||
var href = $(this).attr('href'),
|
||||
external_url_regexp = /https?:\/\/.*/,
|
||||
mailto_regexp = /mailto:.*/,
|
||||
files_regexp = /files\/.*/,
|
||||
images_regexp = /images\/.*/;
|
||||
|
||||
if (!(external_url_regexp.test(href) || mailto_regexp.test(href) || files_regexp.test(href) || images_regexp.test(href))) {
|
||||
$(this).attr('href', "/#" + href);
|
||||
}
|
||||
});
|
||||
|
||||
// Add fullscreen functionality to inline-images and figures
|
||||
$('article.post p > img').click(function () {
|
||||
$(this).get(0).toggleFullScreen();
|
||||
});
|
||||
$('figure').click(function () {
|
||||
$(this).children('img').get(0).toggleFullScreen();
|
||||
});
|
||||
|
||||
// Run current handles onSuccess callback (if it exists)
|
||||
if (handlerCallback.hasOwnProperty('onSuccess') && typeof handlerCallback.onSuccess === 'function') {
|
||||
handlerCallback.onSuccess();
|
||||
}
|
||||
|
||||
// Scroll to top of the page
|
||||
if ($('body').scrollTop() > $('#nav').offset().top - 15) {
|
||||
$('html, body').animate({
|
||||
scrollTop: $('#nav').offset().top - 15
|
||||
}, 'fast');
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init(router) {
|
||||
router.setCallback(loadPageContent);
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#nav-menu a.menuitem').click(function () {
|
||||
$(this).closest('ul').find('li.active').removeClass('active');
|
||||
$(this).closest('li').addClass('active');
|
||||
//$('.navbar-collapse').collapse('hide');
|
||||
});
|
||||
|
||||
$('#status a.close-button').click(function () {
|
||||
$(this).parent().slideUp(function () {
|
||||
$(this).removeClass('error').removeClass('success');
|
||||
$(this).children('p.message').remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var spec = {
|
||||
init: init
|
||||
};
|
||||
return spec;
|
||||
}());
|
||||
// Callback for when the inital page has completely loaded (including images, etc..)
|
||||
$.address.change(function (event) {
|
||||
console.log("Change " + event.value);
|
||||
router.runRouter(event.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var spec = {
|
||||
init: init
|
||||
};
|
||||
return spec;
|
||||
}());
|
||||
|
||||
// Start of execution
|
||||
page.init(router);
|
||||
}(jQuery, MathJax));
|
||||
|
||||
|
@ -86,7 +86,7 @@ has run (using external tools). Hopefully at some point the developers of *GHDL*
|
||||
oversight.
|
||||
|
||||
![[GtkWave][] displaying a simulation dump from *computer_tb* running
|
||||
*src/asm/Fib.hack*](files/images/gtkwave.png)
|
||||
*src/asm/Fib.hack*](/files/images/gtkwave.png)
|
||||
|
||||
Using a
|
||||
[generic property](http://www.doulos.com/knowhow/fpga/Setting_Generics_Parameters_for_Synthesis/)
|
||||
@ -105,7 +105,7 @@ older version of *GHDL* then you must modify `src/computer_tb.vhdl` to specify t
|
||||
want to run in the simulation. See the [documentation][hack-docs] for details.
|
||||
|
||||
![[GtkWave][] zoomed in to view approximately *100 ns* of signal
|
||||
output](files/images/gtkwave-closeup.png)
|
||||
output](/files/images/gtkwave-closeup.png)
|
||||
|
||||
So now that we've seen a quick rundown of how to use the simulator to run *Hack* programs, lets
|
||||
take a moment to review some of the deficiencies of the implementation. The most noticeable
|
||||
|
245
src/site.hs
245
src/site.hs
@ -120,13 +120,14 @@ main = do
|
||||
match "templates/**" $ compile $ getResourceBody >>= saveSnapshot "original"
|
||||
>> templateCompiler
|
||||
|
||||
-- Default Version --------------------------------------------------------------------------------------
|
||||
-- Generate tags
|
||||
tags <- buildTags ("posts/**" .&&. hasNoVersion) (fromCapture "tags/*.html")
|
||||
|
||||
-- Generate paginate
|
||||
paginatedPosts <- buildPaginateWith
|
||||
(fmap (paginateEvery numPaginatePages) . sortRecentFirst)
|
||||
("posts/**" .&&. hasNoVersion)
|
||||
(\n -> fromCapture "pages/blog*.html" (show n))
|
||||
(\n -> fromCapture "blog*.html" (show n))
|
||||
|
||||
pageIds <- getMatches ("pages/**" .&&. complement "pages/blog.markdown")
|
||||
fontIds <- getMatches "fonts/**"
|
||||
@ -190,154 +191,46 @@ main = do
|
||||
-- Generate tag pages
|
||||
paginateTagsRules "tags" tags
|
||||
|
||||
paginateRules paginatedPosts $ \pageNum pattern -> do
|
||||
route idRoute
|
||||
compile $ do
|
||||
posts <- recentFirst =<< loadAllSnapshots pattern "content"
|
||||
let ctx = taggedPostCtx tags <>
|
||||
paginateContext paginatedPosts pageNum <>
|
||||
virtualPaginateContext paginatedPosts pageNum <>
|
||||
constField "weight" "0" <>
|
||||
listField "posts" (taggedPostCtx tags) (return posts)
|
||||
makeItem ""
|
||||
>>= loadAndApplyTemplate "templates/pages/blog.html" ctx
|
||||
|
||||
match "pages/*" $ do
|
||||
route $ setExtension "html"
|
||||
compile $ do
|
||||
-- Get the current page name
|
||||
pageName <- takeBaseName . toFilePath <$> getUnderlying
|
||||
|
||||
posts <- recentFirst =<< loadAllSnapshots ("posts/**" .&&. hasNoVersion) "content"
|
||||
|
||||
let recentPosts = take 5 posts
|
||||
pageTemplate = "templates/pages/" ++ pageName ++ ".html"
|
||||
masterCtx = listField "recentPosts" (taggedPostCtx tags) (return recentPosts) <>
|
||||
listField "posts" (taggedPostCtx tags) (return posts) <>
|
||||
tagCloudField "tagCloud" 65 135 tags <>
|
||||
defaultContext
|
||||
|
||||
sectionCtx <- getResourceBody >>= genSectionContext
|
||||
pg <- loadSnapshot (fromFilePath pageTemplate) "original"
|
||||
>>= applyAsTemplate (sectionCtx <> masterCtx)
|
||||
|
||||
if pageName == "blog"
|
||||
then makeItem ""
|
||||
else makeItem . itemBody $ pg
|
||||
|
||||
match "posts/**" $ do
|
||||
route $ setExtension "html"
|
||||
compile $ pandocCompilerWith pandocReaderOptions pandocWriterOptions
|
||||
>>= saveSnapshot "content"
|
||||
>>= loadAndApplyTemplate "templates/partials/post.html" (taggedPostCtx tags)
|
||||
|
||||
create ["atom.xml"] $ do
|
||||
route idRoute
|
||||
compile $ do
|
||||
let feedCtx = postCtx <> bodyField "description"
|
||||
blogPosts <- loadAllSnapshots ("posts/**" .&&. hasNoVersion) "content"
|
||||
>>= fmap (take 10) . recentFirst
|
||||
renderAtom (feedConfiguration Nothing) feedCtx blogPosts
|
||||
|
||||
forM_ [("js/**", idRoute),
|
||||
("lib/JQuery/*", gsubRoute "JQuery" $ const "js"),
|
||||
("lib/jquery-address/jquery.address.js",
|
||||
customRoute $ const "lib/js/jquery.address.js")] $ \(p, r) ->
|
||||
match p $ do
|
||||
route r
|
||||
compile $ getResourceString >>= withItemBody (unixFilter "jsmin" [])
|
||||
|
||||
create ["index.html"] $ do
|
||||
route idRoute
|
||||
compile $ do
|
||||
-- Generate nav-bar from pages/* ordered by metadata 'weight'
|
||||
pages <- sortByM pageWeight =<< filterM (\i -> pageWeight i >>= return . (> 0)) =<< loadAll ("pages/*" .&&. hasNoVersion)
|
||||
|
||||
let indexCtx = listField "pages" pagesCtx (return pages) <> defaultContext
|
||||
|
||||
makeItem "loading"
|
||||
>>= applyAsTemplate indexCtx
|
||||
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||
|
||||
-- NOJS Version -----------------------------------------------------------------------------------------
|
||||
tagsNoJs <- buildTags ("posts/**" .&&. hasVersion "nojs") (fromCapture "nojs/tags/*.html")
|
||||
|
||||
paginatedPostsNoJs <- buildPaginateWith
|
||||
(fmap (paginateEvery numPaginatePages) . sortRecentFirst)
|
||||
("posts/**" .&&. hasVersion "nojs")
|
||||
(\n -> fromCapture "nojs/blog*.html" (show n))
|
||||
|
||||
-- Generate nojs tag pages
|
||||
paginateTagsRules "nojs/tags" tagsNoJs
|
||||
|
||||
paginateRules paginatedPostsNoJs $ \pageNum pattern -> do
|
||||
route idRoute
|
||||
compile $ do
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
|
||||
posts <- recentFirst =<< loadAllSnapshots pattern "content"
|
||||
let (pagesFirst, pagesLast') = flip span pages $ \x ->
|
||||
(toFilePath . itemIdentifier $ x) /= "pages/blog.markdown"
|
||||
pageMid = [head pagesLast']
|
||||
pagesLast = if not . null $ pagesLast' then tail pagesLast' else []
|
||||
ctx = taggedPostCtx tagsNoJs <>
|
||||
paginateContext paginatedPostsNoJs pageNum <>
|
||||
virtualPaginateContext paginatedPostsNoJs pageNum <>
|
||||
constField "weight" "0" <>
|
||||
listField "posts" (taggedPostCtx tagsNoJs) (return posts)
|
||||
indexCtx = listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
defaultContext
|
||||
|
||||
makeItem ""
|
||||
>>= loadAndApplyTemplate "templates/pages/blog.html" ctx
|
||||
>>= loadAndApplyTemplate "templates/default-nojs.html" indexCtx
|
||||
|
||||
create ["nojs/atom.xml"] $ do
|
||||
route idRoute
|
||||
compile $ do
|
||||
let feedCtx = postCtx <> bodyField "description"
|
||||
blogPosts <- loadAllSnapshots ("posts/**" .&&. hasVersion "nojs") "content"
|
||||
>>= fmap (take 10) . recentFirst
|
||||
renderAtom (feedConfiguration Nothing) feedCtx blogPosts
|
||||
|
||||
match "posts/**" $ version "nojs" $ do
|
||||
route $ customRoute (\r -> "nojs" </> toFilePath r) `composeRoutes` setExtension "html"
|
||||
compile $ do
|
||||
-- Generate nav-bar from pages/*
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
|
||||
let (pagesFirst, pagesLast') = flip span pages $ \x ->
|
||||
(toFilePath . itemIdentifier $ x) /= "pages/blog.markdown"
|
||||
pageMid = [head pagesLast']
|
||||
pagesLast = if not . null $ pagesLast' then tail pagesLast' else []
|
||||
postNojsCtx =
|
||||
listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
defaultContext
|
||||
|
||||
pandocCompilerWith pandocReaderOptions pandocWriterOptions
|
||||
>>= saveSnapshot "content"
|
||||
>>= loadAndApplyTemplate "templates/partials/post.html" postCtx
|
||||
>>= loadAndApplyTemplate "templates/default-nojs.html" postNojsCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
let navgenRoute = customRoute (\r -> if toFilePath r == "pages/home.markdown"
|
||||
then "pages/index.markdown"
|
||||
else toFilePath r) `composeRoutes`
|
||||
gsubRoute "pages" (const "nojs") `composeRoutes`
|
||||
gsubRoute "pages/" (const "") `composeRoutes`
|
||||
setExtension "html"
|
||||
|
||||
match "pages/*" $ version "nav-gen" $ do
|
||||
route navgenRoute
|
||||
compile $ pandocCompiler
|
||||
|
||||
match "pages/*" $ version "nojs" $ do
|
||||
paginateRules paginatedPosts $ \pageNum pattern -> do
|
||||
route idRoute
|
||||
compile $ do
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
posts <- recentFirst =<< loadAllSnapshots pattern "content"
|
||||
|
||||
let (pagesFirst, pagesLast') = flip span pages $ \x ->
|
||||
(toFilePath . itemIdentifier $ x) /= "pages/blog.markdown"
|
||||
pageMid = [head pagesLast']
|
||||
pagesLast = if not . null $ pagesLast' then tail pagesLast' else []
|
||||
|
||||
indexCtx = listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
defaultContext
|
||||
|
||||
ctx = taggedPostCtx tags <>
|
||||
paginateContext paginatedPosts pageNum <>
|
||||
virtualPaginateContext paginatedPosts pageNum <>
|
||||
constField "weight" "0" <>
|
||||
listField "posts" (taggedPostCtx tags) (return posts)
|
||||
makeItem ""
|
||||
>>= loadAndApplyTemplate "templates/pages/blog.html" ctx
|
||||
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
match "pages/*" $ do
|
||||
route navgenRoute
|
||||
compile $ do
|
||||
posts <- recentFirst =<< loadAllSnapshots ("posts/**" .&&. hasVersion "nojs") "content"
|
||||
posts <- recentFirst =<< loadAllSnapshots "posts/**" "content"
|
||||
|
||||
-- Generate nav-bar from pages/*
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
@ -356,10 +249,13 @@ main = do
|
||||
recentPosts = take 5 posts
|
||||
pageTemplate = "templates/pages/" ++ pageName ++ ".html"
|
||||
|
||||
pagesNojsCtx =
|
||||
listField "recentPosts" (taggedPostCtx tagsNoJs) (return recentPosts) <>
|
||||
listField "posts" (taggedPostCtx tagsNoJs) (return posts) <>
|
||||
tagCloudField "tagCloud" 65 135 tagsNoJs <>
|
||||
masterCtx =
|
||||
listField "recentPosts" (taggedPostCtx tags) (return recentPosts) <>
|
||||
listField "posts" (taggedPostCtx tags) (return posts) <>
|
||||
tagCloudField "tagCloud" 65 135 tags <>
|
||||
defaultContext
|
||||
|
||||
indexCtx =
|
||||
listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
@ -367,12 +263,50 @@ main = do
|
||||
|
||||
sectionCtx <- getResourceBody >>= genSectionContext
|
||||
pg <- loadSnapshot (fromFilePath pageTemplate) "original"
|
||||
>>= applyAsTemplate (sectionCtx <> pagesNojsCtx)
|
||||
>>= applyAsTemplate (sectionCtx <> masterCtx)
|
||||
|
||||
(makeItem . itemBody) pg
|
||||
>>= loadAndApplyTemplate "templates/default-nojs.html" pagesNojsCtx
|
||||
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
match "posts/**" $ do
|
||||
route $ setExtension "html"
|
||||
compile $ do
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
|
||||
let (pagesFirst, pagesLast') = flip span pages $ \x ->
|
||||
(toFilePath . itemIdentifier $ x) /= "pages/blog.markdown"
|
||||
pageMid = [head pagesLast']
|
||||
pagesLast = if not . null $ pagesLast' then tail pagesLast' else []
|
||||
|
||||
indexCtx =
|
||||
listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
defaultContext
|
||||
|
||||
pandocCompilerWith pandocReaderOptions pandocWriterOptions
|
||||
>>= saveSnapshot "content"
|
||||
>>= loadAndApplyTemplate "templates/partials/post.html" (taggedPostCtx tags)
|
||||
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
create ["atom.xml"] $ do
|
||||
route idRoute
|
||||
compile $ do
|
||||
let feedCtx = postCtx <> bodyField "description"
|
||||
blogPosts <- loadAllSnapshots ("posts/**" .&&. hasNoVersion) "content"
|
||||
>>= fmap (take 10) . recentFirst
|
||||
renderAtom (feedConfiguration Nothing) feedCtx blogPosts
|
||||
|
||||
forM_ [("js/**", idRoute),
|
||||
("lib/JQuery/*", gsubRoute "JQuery" $ const "js"),
|
||||
("lib/jquery-address/jquery.address.js",
|
||||
customRoute $ const "lib/js/jquery.address.js")] $ \(p, r) ->
|
||||
match p $ do
|
||||
route r
|
||||
compile $ getResourceString >>= withItemBody (unixFilter "jsmin" [])
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- Functions & Constants --------------------------------------------------------------------------------
|
||||
feedConfiguration :: Maybe String -> FeedConfiguration
|
||||
@ -399,13 +333,28 @@ paginateTagsRules loc tags =
|
||||
paginateRules paginatedTaggedPosts $ \pageNum pattern -> do
|
||||
route idRoute
|
||||
compile $ do
|
||||
pages <- sortByM pageWeight =<< loadAll ("pages/*" .&&. hasVersion "nav-gen")
|
||||
posts <- recentFirst =<< loadAllSnapshots pattern "content"
|
||||
let ctx = taggedPostCtx tags <>
|
||||
|
||||
let (pagesFirst, pagesLast') = flip span pages $ \x ->
|
||||
(toFilePath . itemIdentifier $ x) /= "pages/blog.markdown"
|
||||
pageMid = [head pagesLast']
|
||||
pagesLast = if not . null $ pagesLast' then tail pagesLast' else []
|
||||
|
||||
indexCtx = listField "pagesFirst" pagesCtx (return pagesFirst) <>
|
||||
listField "pageMid" pagesCtx (return pageMid) <>
|
||||
listField "pagesLast" pagesCtx (return pagesLast) <>
|
||||
defaultContext
|
||||
|
||||
ctx = taggedPostCtx tags <>
|
||||
paginateContext paginatedTaggedPosts pageNum <>
|
||||
constField "tag" tag <>
|
||||
listField "posts" (taggedPostCtx tags) (return posts)
|
||||
|
||||
makeItem ""
|
||||
>>= loadAndApplyTemplate "templates/tag-page.html" ctx
|
||||
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
rulesExtraDependencies [tagsDependency tags] $ do
|
||||
create [tagsMakeId tags tag] $ do
|
||||
@ -428,7 +377,7 @@ taggedPostCtx :: Tags -> Context String
|
||||
taggedPostCtx tags = tagsField "tags" tags <> postCtx
|
||||
|
||||
pagesCtx :: Context String
|
||||
pagesCtx = field "virtualpath" (fmap (drop 6 . maybe "" toUrl) . getRoute . itemIdentifier) <>
|
||||
pagesCtx = field "virtualpath" (fmap (maybe "" toUrl) . getRoute . itemIdentifier) <>
|
||||
defaultContext
|
||||
|
||||
pageWeight :: (Functor f, MonadMetadata f) => Item a -> f Int
|
||||
@ -468,7 +417,7 @@ virtualPaginateContext pag currentPage = mconcat
|
||||
|
||||
url :: (Int, Identifier) -> Compiler String
|
||||
url (n, i) = getRoute i >>= \mbR -> case mbR of
|
||||
Just r -> return $ drop 6 . toUrl $ r
|
||||
Just r -> return . toUrl $ r
|
||||
Nothing -> fail $ "No URL for page: " ++ show n
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='en'>
|
||||
<head>
|
||||
<!-- Basic Page Needs -->
|
||||
<meta charset='utf-8'>
|
||||
<title>RekahSoft</title>
|
||||
<meta content="The technical musings of a minimalist" name="description">
|
||||
<meta content="Collin Doering" name="author">
|
||||
<meta content="copyright" content="Copyright 2015 - Collin Doering">
|
||||
<meta content="collin, collin doering, rekahsoft, functional programming, math" content="keywords">
|
||||
|
||||
<!-- Mobile Specific Metas -->
|
||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1' name='viewport'>
|
||||
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="/lib/css/normalize.css">
|
||||
<link rel="stylesheet" href="/lib/css/skeleton.css">
|
||||
|
||||
<!-- Custom styles for this template -->
|
||||
<link href='/default.css' rel='stylesheet'>
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href='/images/favicon.ico' rel='shortcut icon'>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<img src="//analytics.rekahsoft.ca/piwik.php?idsite=1" style="border:0;display:none;" alt="" />
|
||||
|
||||
$partial("templates/partials/logo-banner.html")$
|
||||
$partial("templates/partials/nav-nojs.html")$
|
||||
|
||||
<div id="page-content">
|
||||
$body$
|
||||
</div>
|
||||
|
||||
$partial("templates/partials/footer.html")$
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='en' manifest='manifest.appcache'>
|
||||
<html class='en' manifest='/manifest.appcache'>
|
||||
<head>
|
||||
<!-- Basic Page Needs -->
|
||||
<meta charset='utf-8'>
|
||||
@ -13,11 +13,12 @@
|
||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1' name='viewport'>
|
||||
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="lib/css/normalize.css">
|
||||
<link rel="stylesheet" href="lib/css/skeleton.css">
|
||||
<link rel="stylesheet" href="/lib/css/normalize.css">
|
||||
<link rel="stylesheet" href="/lib/css/skeleton.css">
|
||||
|
||||
<!-- Custom styles for this template -->
|
||||
<link href='default.css' rel='stylesheet'>
|
||||
<link href='/default.css' rel='stylesheet'>
|
||||
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href='/images/favicon.ico' rel='shortcut icon'>
|
||||
@ -27,6 +28,7 @@
|
||||
#page-content.init.loading {
|
||||
opacity: 1;
|
||||
height: 100%;
|
||||
background-position: -100px -100px
|
||||
}
|
||||
|
||||
#nav.loading {
|
||||
@ -38,7 +40,7 @@
|
||||
|
||||
<body>
|
||||
<!-- Piwik (no js)-->
|
||||
<noscript><p><img src="//analytics.rekahsoft.ca/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<noscript><img src="//analytics.rekahsoft.ca/piwik.php?idsite=1" style="border:0;display:none;" alt="" /></noscript>
|
||||
|
||||
$partial("templates/partials/logo-banner.html")$
|
||||
$partial("templates/partials/nav.html")$
|
||||
@ -58,15 +60,17 @@
|
||||
</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
$body$
|
||||
</div>
|
||||
$partial("templates/partials/footer.html")$
|
||||
|
||||
<!-- External javascript libraries: JQuery, and JQuery-Address -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src='lib/js/jquery-1.11.2.js' type='text/javascript'></script>
|
||||
<script src='lib/js/jquery.address.js' type='text/javascript'></script>
|
||||
<script src='/lib/js/jquery-1.11.2.js' type='text/javascript'></script>
|
||||
<script src='/lib/js/jquery.address.js' type='text/javascript'></script>
|
||||
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML' type='text/javascript'></script>
|
||||
<!-- Custom javascript for user interactivity -->
|
||||
<script src='js/default.js' type='text/javascript'></script>
|
||||
<script src='/js/default.js' type='text/javascript'></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,20 +0,0 @@
|
||||
<div id='nav'>
|
||||
<ul class="container" id='nav-menu'>
|
||||
$for(pagesFirst)$
|
||||
<li>
|
||||
<a class='menuitem' href='$url$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
$for(pageMid)$
|
||||
<li class='active'>
|
||||
<a class='menuitem' href='$url$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
$for(pagesLast)$
|
||||
<li>
|
||||
<a class='menuitem' href='$url$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
<a class='rss-icon' href='atom.xml'></a>
|
||||
</ul>
|
||||
</div>
|
@ -1,8 +1,18 @@
|
||||
<div class='loading' id='nav'>
|
||||
<ul class='container' id='nav-menu'>
|
||||
$for(pages)$
|
||||
<div class="loading" id='nav'>
|
||||
<ul class="container" id='nav-menu'>
|
||||
$for(pagesFirst)$
|
||||
<li>
|
||||
<a class='menuitem' href='/#$virtualpath$' rel='address:$virtualpath$'>$title$</a>
|
||||
<a class='menuitem' href='$url$' rel='address:$virtualpath$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
$for(pageMid)$
|
||||
<li class='active'>
|
||||
<a class='menuitem' href='$url$' rel='address:$virtualpath$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
$for(pagesLast)$
|
||||
<li>
|
||||
<a class='menuitem' href='$url$' rel='address:$virtualpath$'>$title$</a>
|
||||
</li>
|
||||
$endfor$
|
||||
<a class='rss-icon' href='atom.xml'></a>
|
||||
|
Loading…
Reference in New Issue
Block a user