Commit a91d8ed4 authored by Aaron Harder's avatar Aaron Harder

Lots of changes to support Documentation tools

parent 5c80c992
......@@ -8,9 +8,8 @@ The module expects to find two key files added to your component definition fold
* `dialog.js` which describes the fields that go inside that particular component resource type.
* `container.js` which describes the child components that go inside that particular component resource type.
Each `dialog.js` describes a series of panels, tabs or fieldsets which contain lists of fields, which in turn reference widgets of various types. The list of available "default" widgets can be found in the blacklight-edit module itself, at `apps/blacklight/wdit/widgets`.
Each `dialog.js` describes a series of panels, tabs or fieldsets which contain lists of fields, which in turn reference widgets of various types. The list of available "default" widgets can be found in the blacklight-edit module itself, at `apps/blacklight/edit/widgets`.
Each `container.js` describes the set of child component types that it `includes` (if any). One special type of container is the `Editable Component Container` (`ECC`) which alows authors to dynamically determine how many and what kind of child components to include in a parent component. The ECC behaviour can be controlled by declaring allowed `eccItems` in your `includes` definition for that ECC.
// TEMPLATE WIZ: Templates worth wizzing on!
// (c) 1984 Alphasoft
/**
* Process a template with tags of
* Format: [[data_key]] or [[myFilter:data_key]] or [[my_filter:my_other_filter:"literal-value"]]
**/
module.exports=function templateMaker(options){
return function templateReplace(template, data){
data=data||{};
var defaultFilters={
quote:function(value){return value.replace(/(['"])/g, '\\$1');}
};
var result = template.replace(/\[\[((?:\w+:?)+)(?:"(.*)")?\]\]/g, function(match, tags, literal){
var filters=tags.replace(/:$/,"").split(":"), filter;
var value = literal || data[filters.pop()] || "";
while(filters.length){
filter=filters.pop();
if(options.filters && options.filters[filter]){
value = options.filters[filter](value);
}else{
if(defaultFilters[filter]){value = defaultFilters[filter](value);}
else{value="Missing filter '" + filter + "' " + value;}
}
}
return value;
});
return result;
};
}
......@@ -67,13 +67,13 @@ module.exports = function blEditRouter(routerSettings){
var slingProxyPrefix = slingProxyType?"":(global.bl.appsMount + "blacklight/edit/proxy/");
var blConfig = {publicMount: global.bl.publicMount, appsMount: global.bl.appsMount, hasPageListingCapability: config.slingConnectors.author.hasPageListingCapability, slingProxyPrefix:slingProxyPrefix, defaultModule : config.defaultModule};
$={
express:{req:req, res:res, next:next}, sc:sc, hb: hb, log:log,
componentRegistry: componentRegistry, widgetRegistry: widgetRegistry,
slingProxyType:slingProxyType, slingProxyPrefix: slingProxyPrefix,
handleError: handleError, blConfig: blConfig,
action:action, mainPath: req.params.mainPath, mainExtension: req.params.mainExtension
action:action, mainPath: req.params.mainPath, mainExtension: req.params.mainExtension,
templates:routerSettings.templates.blacklight.edit
}
var method = methods[action];
......
......@@ -2,7 +2,10 @@ var _path=require("path");
var config=require("config");
var _=require("lodash");
var fs=require("fs");
var templateWizFactory=require("../../lib/template-wiz.js");
var blacklight=require("blacklight-render");
var ALL_DOCS_INDEX=1, SITE_INDEX=2, MODULE_INDEX=3;
var ALL_DOCS_SELECTOR_SEGMENT=0, SITE_SEGMENT=1, MODULE_SEGMENT=2;
......@@ -11,6 +14,34 @@ module.exports=function(data, $, cb){
things: true
}
data.modes={
view:{icon:"visibility"},
edit:{icon:"mode_edit"}
}
///////////////////////////////////////////////////////////////////////
var preprocessMarkdown = templateWizFactory({filters:{
include:function(value){
var moduleRoot=_path.join(global.bl.appRoot, "blacklight_modules", site, module), result;
var path;
if(value.toLowerCase()==="readme.md"){
path=_path.join(moduleRoot,"README.md");
}else{
if(value[0]==="."){if(value[1]==="."){return "Bad include path:"+value;} path=_path.join(docRoot,value)}
else{path=_path.join(moduleRoot,"docs",value);}
}
try{
result = fs.readFileSync(path);
}catch(err){
return "ERROR: Couldn't read file: " + path;
}
return preprocessMarkdown(result.toString());
}
}})
var req=$.express.req;
var res=$.express.res;
var sc=$.sc;
......@@ -60,8 +91,17 @@ module.exports=function(data, $, cb){
/////////////////////////////////////////////////////////////////////
var renderHtml = function (markdown){
res.end(global.bl.marked(markdown.toString()));
var renderMarkdown = function (markdown){
markdown = preprocessMarkdown(markdown.toString());
var html=$.templates["doc-page"]({body: global.bl.marked(markdown), blConfig:$.blConfig});
res.end(html);
};
/////////////////////////////////////////////////////////////////////
var renderHtml = function (body, otherData){
var data = _.assign({body: body, blConfig:$.blConfig}, otherData)
return $.templates["doc-page"](data);
};
......@@ -73,6 +113,7 @@ module.exports=function(data, $, cb){
/////////////////////////////////////////////////////////////////////
case ALL_DOCS_INDEX:
_.each(config.modules.sites,function(site,key){
pages.push({path:_path.join(urlBase, key), title:site.title, childPagesCount: 1})
})
......@@ -81,7 +122,9 @@ module.exports=function(data, $, cb){
/////////////////////////////////////////////////////////////////////
case SITE_INDEX:
res.send("Site-level index");
var base=config.modules.sites[site].baseModule;
var target=_path.join(urlBase, base + "/tutorials");
res.send(renderHtml("", {redirect: target} ));
break;
......@@ -90,12 +133,12 @@ module.exports=function(data, $, cb){
var tutIndex=_path.join(docRoot,"tutorials.md");
fs.readFile(tutIndex, function(err, markdown){
if(!err){
renderHtml(markdown);
renderMarkdown(markdown);
}else{
var readme=_path.join(docRoot,"../README.md");
fs.readFile(readme, function(err, markdown){
if(err){res.status(404).end("Could not find file:<br><tt>" + readme + "</tt><br>or:<br><tt>" + tutIndex + "</tt>"); return;}
renderHtml(markdown);
if(err){res.status(404).end(renderHtml("Could not find file:<br><br><tt>" + readme + "</tt><br>or:<br><tt>" + tutIndex + "</tt><br><br>You may wish to create a file here.")); return;}
renderMarkdown(markdown);
});
}
});
......@@ -104,8 +147,8 @@ module.exports=function(data, $, cb){
default:
fs.readFile(docRoot + ".md", function(err, markdown){
if(err){res.status(404).end("Could not find file: " + path); return;}
renderHtml(markdown);
if(err){res.status(404).end(renderHtml("Could not find file:<br><br><tt>" + docRoot + ".md" + "</tt><br><br>You may wish to create a file here.")); return;}
renderMarkdown(markdown);
})
}
}else{
......@@ -126,6 +169,7 @@ module.exports=function(data, $, cb){
case SITE_INDEX:
fs.readdir(docRoot,function(err,files){
if(err){var msg="Error reading: " + docRoot; console.error(msg); res.json({pages:[{title:msg}]}); return;}
files.sort();
var pages=[];
function checkForDocs(){
if(files.length){
......@@ -133,7 +177,7 @@ module.exports=function(data, $, cb){
var curRoot=_path.join(docRoot, file);
fs.stat(_path.join(curRoot, "docs"),function(err,stat){
var childPagesCount=err?0:1;
pages.push({path:_path.join(urlBase, file), title: blacklight.prettyName(file), childPagesCount:childPagesCount});
pages.push({path:_path.join(urlBase, file), title: blacklight.prettyName(file.replace(/^\d+-/,"")), childPagesCount:childPagesCount});
checkForDocs();
});
}else{
......@@ -155,7 +199,7 @@ module.exports=function(data, $, cb){
var match=file.match(/^(.*)\.md$/);
if(match){
var name=match[1], hasChildren=files.indexOf(name)>-1;
pages.push({path: _path.join(urlBase, name), title: blacklight.prettyName(name), childPagesCount: hasChildren?1:0})
pages.push({path: _path.join(urlBase, name), title: blacklight.prettyName(name.replace(/^\d+-/,"")), childPagesCount: hasChildren?1:0})
}
}
res.json({pageCount:pages.length, pages:pages})
......
......@@ -14,5 +14,49 @@ module.exports=function(data, $, cb){
data.scripts.css.unshift("blacklight/edit/css/vendor/ui.fancytree.min.css");
data.modes={
view:{icon:"visibility", title:"Page preview"},
edit:{icon:"mode_edit", title:"Edit view"},
list:{icon:"view_list", title:"Page list view"},
raw:{icon:"view_quilt", title:"Data view"},
live:{icon:"public", title:"Live view"}
}
data.menuItems={
settings:{
linkAttributes:'data-target="bl-edit-dialog" data-sling-type="blacklight/edit/page/resource-type"',
title:"Page settings" },
add:{
linkAttributes:'data-target="bl-add-page-dialog"',
title:"Add page"},
delete:{
linkAttributes:'data-target="bl-delete-page-dialog"',
title:"Delete page", divider:true },
copy:{
title:"Copy page", icon:"content_copy"},
cut:{
title:"Cut page", icon:"content_cut"},
paste:{
title:"Paste page", icon:"content_paste", divider: true, disabled: true},
approve:{
title:"Approve content", icon:"check_circle", mode:true},
publish:{
title:"Publish content", icon:"get_app", mode:true},
transfer:{
title:"Transfer content", icon:"input", mode:true},
}
cb();
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<title>Blacklight Documentation</title>
<link rel="stylesheet" href="{{@root.blConfig.publicMount}}blacklight/edit/js/vendor/highlight/agate.min.css">
<link rel="stylesheet" href="{{blConfig.publicMount}}blacklight/edit/css/doc.css"/>
</head>
<body>
{{#if redirect}}
<b>Redirecting to:</b>&nbsp; {{redirect}}
<script>
var parent=window.parent;
parent.BL.view.path("{{redirect}}");
parent.BL.view.applyPathAndMode();
</script>
{{/if}}
{{{body}}}
</body>
<script src="{{@root.blConfig.publicMount}}blacklight/edit/js/vendor/jquery/jquery-2.1.1.min.js"></script>
<script src="{{@root.blConfig.publicMount}}blacklight/edit/js/vendor/highlight/highlight.min.js"></script>
<script src="{{@root.blConfig.publicMount}}blacklight/edit/js/doc-markdown-client.js"></script>
</html>
\ No newline at end of file
......@@ -16,28 +16,28 @@
<a id="bl-reload" class="btn right blue accent-2 tooltipped" style="margin-top:0px;margin-right:8px;" data-tooltip="Refresh view" data-position="top"><i class="material-icons dp32">refresh</i></a>
<a class="btn blue accent-2 tooltipped" data-mode="view" data-tooltip="Page preview" data-position="top"><i class="material-icons dp32">visibility</i></a>
<a class="btn blue accent-2 tooltipped" data-mode="edit" data-tooltip="Edit view" data-position="top"><i class="material-icons dp32">mode_edit</i></a>
<a class="btn blue accent-2 tooltipped" data-mode="list" data-tooltip="Page list view" data-position="top"><i class="material-icons dp32">view_list</i></a>
<a class="btn blue accent-2 tooltipped" data-mode="raw" data-tooltip="Data view" data-position="top"><i class="material-icons dp32">view_quilt</i></a>
<a class="btn blue accent-2 tooltipped" data-mode="live" data-tooltip="Live view" data-position="top"><i class="material-icons dp32">public</i></a>
{{#each @root.modes}}
<a class="btn blue accent-2 tooltipped" data-mode="{{@key}}" data-tooltip="{{first-of title (prettyname @key)}}" data-position="top"><i class="material-icons dp32">{{icon}}</i></a>
{{/each}}
&nbsp;&nbsp;&nbsp;
<a class="btn blue accent-2 dropdown-button" data-activates="page-actions" data-alignment="left" data-beloworigin="true" data-constrainwidth="false" data-position="top"><i class="material-icons dp32">menu</i></a>
<ul id="page-actions" class="dropdown-content" style="background-color:#E4ECFB;">
<li><a data-action="settings" data-target="bl-edit-dialog" data-sling-type="blacklight/edit/page/resource-type"><i class="material-icons small">settings</i>Page settings</a></li>
<li><a data-action="add" data-target="bl-add-page-dialog"><i class="material-icons small">add_circle</i>Add page</a></li>
<li><a data-action="delete" data-target="bl-delete-page-dialog"><i class="material-icons small">delete</i>Delete page</a></li>
<li class="divider"></li>
<li><a class=""><i class="material-icons small">content_copy</i>Copy page</a></li>
<li><a class=""><i class="material-icons small">content_cut</i>Cut page</a></li>
<li class="disabled"><a><i class="material-icons small">content_paste</i>Paste page</a></li>
<li class="divider"></li>
<li><a data-mode="approve" class=""><i class="material-icons small">check_circle</i>Approve content</a></li>
<li><a data-mode="publish" class=""><i class="material-icons small">get_app</i>Publish content</a></li>
<li><a data-mode="transfer" class=""><i class="material-icons small">input</i>Transfer content</a></li>
</ul>
{{#if @root.menuItems}}
<a class="btn blue accent-2 dropdown-button" data-activates="page-actions" data-alignment="left" data-beloworigin="true" data-constrainwidth="false" data-position="top"><i class="material-icons dp32">menu</i></a>
<ul id="page-actions" class="dropdown-content" style="background-color:#E4ECFB;">
{{#each @root.menuItems}}
<li {{#if disabled}}class="disabled"{{/if}}><a data-{{#if mode}}mode{{else}}action{{/if}}="{{@key}}" {{{linkAttributes}}}><i class="material-icons small">{{first-of icon @key}}</i>{{title}}</a></li>
{{#if divider}}<li class="divider"></li>{{/if}}
{{/each}}
</ul>
{{/if}}
<div id="bl-loading" class="progress blue lighten-4" style="height: 2px;">
<div class="indeterminate blue accent-2" style="width:100%"></div>
......
......@@ -32,7 +32,7 @@
<div class="nav-wrapper container">
<div class="row">
<div class="col s12">
<a href="#" class="brand-logo right">
<a href="{{@root.blConfig.appsMount}}blacklight/edit/home" class="brand-logo right">
{{!-- <img src="{{publicMount}}blacklight/edit/images/blk-light.svg" style="height:38px;position:relative; top:12px; left:8px;"> --}}
<img src="{{publicMount}}blacklight/edit/images/wordmark-2.svg" >
{{!-- <img src="{{publicMount}}blacklight/edit/images/blacklight-bulb-white.svg" style="height:42px;position:relative; top:12px; left:-10px;"> --}}
......
h1, h2, h3, h4, h5, h6, p, blockquote {
margin: 0;
padding: 0;
}
body {
font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
font-size: 14px;
line-height: 18px;
color: #737373;
background-color: white;
margin: 10px 13px 10px 13px;
}
table {
margin: 10px 0 15px 0;
border-collapse: collapse;
}
td,th {
border: 1px solid #ddd;
padding: 3px 10px;
}
th {
padding: 5px 10px;
}
a {
color: #0069d6;
}
a:hover {
color: #0050a3;
text-decoration: none;
}
a img {
border: none;
}
p {
margin-bottom: 9px;
margin-right: 9px;
}
h1, h2, h3, h4, h5, h6 {
color: #822;
line-height: 36px;
}
h1 {
color:#822;
margin-bottom: 9px;
font-size: 30px;
margin-top: 32px;
border-top: 1px solid #aaa;
background-color: #eaecf6;
line-height: 150%;
}
h2 {
font-size: 24px;
margin-top:1.5em;
}
h3 {
font-size: 18px;
margin-top:1em;
}
h4 {
font-size: 16px;
}
h5 {
font-size: 14px;
}
h6 {
font-size: 13px;
}
hr {
margin: 0 0 19px;
border: 0;
border-bottom: 1px solid #ccc;
}
blockquote {
padding: 13px 13px 21px 15px;
margin-bottom: 18px;
font-family:georgia,serif;
font-style: italic;
}
blockquote:before {
content:"\201C";
font-size:40px;
margin-left:-10px;
font-family:georgia,serif;
color:#eee;
}
blockquote p {
font-size: 14px;
font-weight: 300;
line-height: 18px;
margin-bottom: 0;
font-style: italic;
}
code, pre {
font-family: Monaco, Andale Mono, Courier New, monospace;
}
code {
background-color: #f2e8e8;
color: #8a3131;
padding: 0px;
font-size: 13px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
margin-left: 2px;
margin-right: 2px;
padding-left: 6px;
padding-right: 6px;
}
.hljs{
padding:1em;
}
pre {
display: block;
padding: 2px 0px;
margin: 24px 0;
line-height: 16px;
background-color: #282b2e;
font-size: 11px;
border: 1px solid #d9d9d9;
white-space: pre-wrap;
word-wrap: break-word;
}
pre code {
background-color: #fff;
color:#737373;
font-size: 13px;
padding: 0;
}
sup {
font-size: 0.83em;
vertical-align: super;
line-height: 0;
}
ul {
margin-top: 4px;
margin-bottom: 18px;
}
img.fancy{
margin-bottom:.25em;
}
img.border{
border:1px solid #777;
}
.image-container.border img.border{
border:none;
}
.image-container.border{
border:1px solid #777;
}
img.shadow{
box-shadow: 0px 0px 25px 2px rgba(0,0,0,0.30);
margin-top:2em;
margin-bottom:2em;
}
.image-container.shadow img.shadow{
box-shadow: none;
margin-top: 1em;
margin-bottom: .25em;
}
.image-container.shadow{
box-shadow: 0px 0px 25px 2px rgba(0,0,0,0.30);
margin-top:2em;
margin-bottom:2em;
padding-bottom:.1em;
}
img.fancy.left, .image-container.left{
float:left;
margin-right:1em;
}
img.fancy.right, .image-container.right{
float:right;
margin-left:1em;
}
img.center, .image-container.center{
margin-left:auto;
margin-right:auto;
display:block;
text-align: center;
}
.image-container{
margin-bottom:.25em;
}
.image-caption{
font-style:italic;
color:#369;
}
.image-container.border .image-caption{
margin:.25em;
}
.image-container.shadow .image-caption{
margin:.5em;
}
* {
-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
body {
margin: 30px 34px;
max-width:900px;
}
}
@media print {
body,code,pre code,h1,h2,h3,h4,h5,h6 {
color: black;
}
table, pre {
page-break-inside: avoid;
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/* globals hljs, $ */
if(hljs){ hljs.initHighlightingOnLoad(); }
$(function(){
$("img[data-rollover]").each(function(){
var $image = $(this);
var normal=$image.attr("src");
var parts=normal.match(/(.*?)([^\/]*)$/);
var rollover=parts[1] + $image.data("rollover");
console.log("ROLLOVER:", $image)
$image.click(function(){console.log("CLICK");})
$image.hover(
function(){
$image.attr("src", rollover);
},
function(){
$image.attr("src", normal);
}
)
});
$("img[data-clearfix]").each(function(){
var $image=$(this);
var clearfix=$image.data("clearfix");
if(clearfix){
var clearme=$image.parent().nextAll().eq(clearfix-1);
$("<br style='clear:both'>").insertBefore(clearme);
}
})
});
......@@ -7,7 +7,9 @@ module.exports=function($, window){
var $modeButtons, modeButtons={}, currentMode="view", currentPath;
var $iframe, $loadingIndicator;
var dialog = window.BL.dialog;
var $document=$(document);
var $document=$(window.document);
window.BL.view=view;
$.extend(view, {
publicMount: $("body").data("public-mount"),
......@@ -25,7 +27,7 @@ module.exports=function($, window){
activate: onTreeClick,
dblclick: onTreeClick,
loadChildren: function(event,data){
applyPathAndMode();