diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py
index 998cce70cb..9744d4ac8b 100644
--- a/akvo/rsr/models/project.py
+++ b/akvo/rsr/models/project.py
@@ -151,16 +151,22 @@ class Project(TimestampsMixin, models.Model):
goals_overview = ValidXMLTextField(
_(u'goals overview'), blank=True,
- help_text=_(u'Provide a brief description of the overall project goals.')
+ help_text=_(u'Provide a brief description of the overall project goals. For links and '
+ u'styling of the text, Markdown is supported.')
)
current_status = ValidXMLTextField(
_(u'baseline situation'), blank=True,
- help_text=_(u'Describe the situation at the start of the project.')
+ help_text=_(u'Describe the situation at the start of the project. For links and styling of '
+ u'the text, Markdown is supported.')
)
project_plan = ValidXMLTextField(
_(u'project plan'), blank=True,
help_text=_(u'Detailed information about the implementation of the project: the what, how, '
- u'who and when.')
+ u'who and when. For links and styling of the text, Markdown '
+ u'is supported.')
)
sustainability = ValidXMLTextField(
_(u'sustainability'), blank=True,
@@ -168,18 +174,24 @@ class Project(TimestampsMixin, models.Model):
u'years after project implementation. Think about the institutional setting, '
u'capacity-building, a cost recovery plan, products used, feasible '
u'arrangements for operation and maintenance, anticipation of environmental '
- u'impact and social integration.')
+ u'impact and social integration. For links and styling of the text, '
+ u'Markdown is supported.')
)
background = ValidXMLTextField(
_(u'background'), blank=True,
help_text=_(u'This should describe the geographical, political, environmental, social '
u'and/or cultural context of the project, and any related activities that '
- u'have already taken place or are underway.')
+ u'have already taken place or are underway. For links and styling of the text, '
+ u'Markdown is supported.')
)
target_group = ProjectLimitedTextField(
_(u'target group'), blank=True,
help_text=_(u'This should include information about the people, organisations or resources '
- u'that are being impacted by this project.')
+ u'that are being impacted by this project. For links and styling of the text, '
+ u'Markdown is supported.')
)
# Results framework (always on)
diff --git a/akvo/rsr/static/lib/scripts/micromarkdown-0.3.4.js b/akvo/rsr/static/lib/scripts/micromarkdown-0.3.4.js
new file mode 100644
index 0000000000..ad1906144f
--- /dev/null
+++ b/akvo/rsr/static/lib/scripts/micromarkdown-0.3.4.js
@@ -0,0 +1,10 @@
+/* * * * * * * * * * * *
+ * micromarkdown .js *
+ * Version 0.3.4 *
+ * License: MIT *
+ * Simon Waldherr *
+ * * * * * * * * * * * */
+
+var micromarkdown={useajax:!1,regexobject:{headline:/^(\#{1,6})([^\#\n]+)$/m,code:/\s\`\`\`\n?([^`]+)\`\`\`/g,hr:/^(?:([\*\-_] ?)+)\1\1$/gm,lists:/^((\s*((\*|\-)|\d(\.|\))) [^\n]+)\n)+/gm,bolditalic:/(?:([\*_~]{1,3}))([^\*_~\n]+[^\*_~\s])\1/g,links:/!?\[([^\]<>]+)\]\(([^ \)<>]+)( "[^\(\)\"]+")?\)/g,reflinks:/\[([^\]]+)\]\[([^\]]+)\]/g,smlinks:/\@([a-z0-9]{3,})\@(t|gh|fb|gp|adn)/gi,mail:/<(([a-z0-9_\-\.])+\@([a-z0-9_\-\.])+\.([a-z]{2,7}))>/gim,tables:/\n(([^|\n]+ *\| *)+([^|\n]+\n))((:?\-+:?\|)+(:?\-+:?)*\n)((([^|\n]+ *\| *)+([^|\n]+)\n)+)/g,include:/[\[<]include (\S+) from (https?:\/\/[a-z0-9\.\-]+\.[a-z]{2,9}[a-z0-9\.\-\?\&\/]+)[\]>]/gi,url:/<([a-zA-Z0-9@:%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}\b(\/[\-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)?)>/g,url2:/[ \t\n]([a-zA-Z]{2,16}:\/\/[a-zA-Z0-9@:%_\+.~#?&=]{2,256}.[a-z]{2,4}\b(\/[\-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)?)[ \t\n]/g},codeblocks:{},parse:function(a,b){"use strict";var c,d,e,f,g,h,i,j,k,l,m,n=0,o=[],p=0,q=0,r=0,s="";for(a="\n"+a+"\n",b!==!0&&(micromarkdown.regexobject.lists=/^((\s*(\*|\d\.) [^\n]+)\n)+/gm),a=a.replace("$&","$&");null!==(m=micromarkdown.regexobject.code.exec(a));)s=micromarkdown.crc32(m[0]),micromarkdown.codeblocks[s]="\n"+micromarkdown.htmlEncode(m[1]).replace(/\n/gm,"
").replace(/\ /gm," ")+"
\n",a=a.replace(m[0]," §§§"+s+"§§§ ");for(;null!==(m=micromarkdown.regexobject.headline.exec(a));)k=m[1].length,a=a.replace(m[0],""+m[2]+"\n");for(;null!==(m=micromarkdown.regexobject.lists.exec(a));){for(p=0,l="*"===m[0].trim().substr(0,1)||"-"===m[0].trim().substr(0,1)?"
":"",h=m[0].split("\n"),i=[],d=0,g=!1,q=0;qn;)l+=i.pop(),d--,p--;for(;n>d;)"*"===c[0].trim().substr(0,1)||"-"===c[0].trim().substr(0,1)?(l+="")):(l+="",i.push("
")),d++,p++;l+="- "+c[6]+"
\n"}for(;p>0;)l+="
",p--;l+="*"===m[0].trim().substr(0,1)||"-"===m[0].trim().substr(0,1)?"":"",a=a.replace(m[0],l+"\n")}for(;null!==(m=micromarkdown.regexobject.tables.exec(a));){for(l="",h=m[1].split("|"),f=m[4].split("|"),q=0;q",'',' | ',' | '],q=0;q";for(l+=" |
",e=["",' | ',' | ',' | '],i=m[7].split("\n"),q=0;q",r=0;r";l+="\n"}l+=" |
",a=a.replace(m[0],l)}for(q=0;3>q;q++)for(;null!==(m=micromarkdown.regexobject.bolditalic.exec(a));)if(l=[],"~~"===m[1])a=a.replace(m[0],""+m[2]+"");else{switch(m[1].length){case 1:l=["",""];break;case 2:l=["",""];break;case 3:l=["",""]}a=a.replace(m[0],l[0]+m[2]+l[1])}for(;null!==(m=micromarkdown.regexobject.links.exec(a));)a="!"===m[0].substr(0,1)?a.replace(m[0],'\n'):a.replace(m[0],"'+m[1]+"\n");for(;null!==(m=micromarkdown.regexobject.mail.exec(a));)a=a.replace(m[0],''+m[1]+"");for(;null!==(m=micromarkdown.regexobject.url.exec(a));)l=m[1],-1===l.indexOf("://")&&(l="http://"+l),a=a.replace(m[0],"'+l.replace(/(https:\/\/|http:\/\/|mailto:|ftp:\/\/)/gim,"")+"");for(;null!==(m=micromarkdown.regexobject.reflinks.exec(a));)i=new RegExp("\\["+m[2]+"\\]: ?([^ \n]+)","gi"),null!==(h=i.exec(a))&&(a=a.replace(m[0],"'+m[1]+""),o.push(h[0]));for(q=0;q'+m[1]+"")}for(;null!==(m=micromarkdown.regexobject.url2.exec(a));)l=m[1],a=a.replace(m[0],"'+l+"");for(;null!==(m=micromarkdown.regexobject.hr.exec(a));)a=a.replace(m[0],"\n
\n");if(micromarkdown.useajax!==!1&&b!==!0)for(;null!==(m=micromarkdown.regexobject.include.exec(a));)if(h=m[2].replace(/[\.\:\/]+/gm,""),i="",document.getElementById(h)?i=document.getElementById(h).innerHTML.trim():micromarkdown.ajax(m[2]),"csv"===m[1]&&""!==i){for(j={";":[]," ":[],",":[],"|":[]},j[0]=[";"," ",",","|"],i=i.split("\n"),r=0;r0&&j[j[0][r]]!==!1&&(j[j[0][r]][q]!==j[j[0][r]][q-1]||1===j[j[0][r]][q])&&(j[j[0][r]]=!1);if(j[";"]!==!1||j[" "]!==!1||j[","]!==!1||j["|"]!==!1){for(j[";"]!==!1?j=";":j[" "]?j=" ":j[","]?j=",":j["|"]&&(j="|"),l="",q=0;q",r=0;r"+micromarkdown.htmlEncode(h[r])+"";l+=""}l+="
",a=a.replace(m[0],l)}else a=a.replace(m[0],""+i.join("\n")+"
")}else a=a.replace(m[0],"");a=a.replace(/ {2,}[\n]{1,}/gim,"
"),a=a.replace(/[\n]{2,}/gim,"
");for(var t in micromarkdown.codeblocks)micromarkdown.codeblocks.hasOwnProperty(t)&&(a=a.replace("§§§"+t+"§§§",micromarkdown.codeblocks[t]));return a=a.replace("$&","$&")},ajax:function(a){"use strict";var b;if(document.getElementById(a.replace(/[\.\:\/]+/gm,"")))return!1;if(window.ActiveXObject)try{b=new ActiveXObject("Microsoft.XMLHTTP")}catch(c){return b=null,c}else b=new XMLHttpRequest;b.onreadystatechange=function(){if(4===b.readyState){var c=document.createElement("code");c.innerHTML=b.responseText,c.id=a.replace(/[\.\:\/]+/gm,""),c.style.display="none",document.getElementsByTagName("body")[0].appendChild(c),micromarkdown.useajax()}},b.open("GET",a,!0),b.setRequestHeader("Content-type","application/x-www-form-urlencoded"),b.send()},crc32:function(a){"use strict";var b,c,d,e,f=0,g=["00000000","77073096","EE0E612C","990951BA","076DC419","706AF48F","E963A535","9E6495A3","0EDB8832","79DCB8A4","E0D5E91E","97D2D988","09B64C2B","7EB17CBD","E7B82D07","90BF1D91","1DB71064","6AB020F2","F3B97148","84BE41DE","1ADAD47D","6DDDE4EB","F4D4B551","83D385C7","136C9856","646BA8C0","FD62F97A","8A65C9EC","14015C4F","63066CD9","FA0F3D63","8D080DF5","3B6E20C8","4C69105E","D56041E4","A2677172","3C03E4D1","4B04D447","D20D85FD","A50AB56B","35B5A8FA","42B2986C","DBBBC9D6","ACBCF940","32D86CE3","45DF5C75","DCD60DCF","ABD13D59","26D930AC","51DE003A","C8D75180","BFD06116","21B4F4B5","56B3C423","CFBA9599","B8BDA50F","2802B89E","5F058808","C60CD9B2","B10BE924","2F6F7C87","58684C11","C1611DAB","B6662D3D","76DC4190","01DB7106","98D220BC","EFD5102A","71B18589","06B6B51F","9FBFE4A5","E8B8D433","7807C9A2","0F00F934","9609A88E","E10E9818","7F6A0DBB","086D3D2D","91646C97","E6635C01","6B6B51F4","1C6C6162","856530D8","F262004E","6C0695ED","1B01A57B","8208F4C1","F50FC457","65B0D9C6","12B7E950","8BBEB8EA","FCB9887C","62DD1DDF","15DA2D49","8CD37CF3","FBD44C65","4DB26158","3AB551CE","A3BC0074","D4BB30E2","4ADFA541","3DD895D7","A4D1C46D","D3D6F4FB","4369E96A","346ED9FC","AD678846","DA60B8D0","44042D73","33031DE5","AA0A4C5F","DD0D7CC9","5005713C","270241AA","BE0B1010","C90C2086","5768B525","206F85B3","B966D409","CE61E49F","5EDEF90E","29D9C998","B0D09822","C7D7A8B4","59B33D17","2EB40D81","B7BD5C3B","C0BA6CAD","EDB88320","9ABFB3B6","03B6E20C","74B1D29A","EAD54739","9DD277AF","04DB2615","73DC1683","E3630B12","94643B84","0D6D6A3E","7A6A5AA8","E40ECF0B","9309FF9D","0A00AE27","7D079EB1","F00F9344","8708A3D2","1E01F268","6906C2FE","F762575D","806567CB","196C3671","6E6B06E7","FED41B76","89D32BE0","10DA7A5A","67DD4ACC","F9B9DF6F","8EBEEFF9","17B7BE43","60B08ED5","D6D6A3E8","A1D1937E","38D8C2C4","4FDFF252","D1BB67F1","A6BC5767","3FB506DD","48B2364B","D80D2BDA","AF0A1B4C","36034AF6","41047A60","DF60EFC3","A867DF55","316E8EEF","4669BE79","CB61B38C","BC66831A","256FD2A0","5268E236","CC0C7795","BB0B4703","220216B9","5505262F","C5BA3BBE","B2BD0B28","2BB45A92","5CB36A04","C2D7FFA7","B5D0CF31","2CD99E8B","5BDEAE1D","9B64C2B0","EC63F226","756AA39C","026D930A","9C0906A9","EB0E363F","72076785","05005713","95BF4A82","E2B87A14","7BB12BAE","0CB61B38","92D28E9B","E5D5BE0D","7CDCEFB7","0BDBDF21","86D3D2D4","F1D4E242","68DDB3F8","1FDA836E","81BE16CD","F6B9265B","6FB077E1","18B74777","88085AE6","FF0F6A70","66063BCA","11010B5C","8F659EFF","F862AE69","616BFFD3","166CCF45","A00AE278","D70DD2EE","4E048354","3903B3C2","A7672661","D06016F7","4969474D","3E6E77DB","AED16A4A","D9D65ADC","40DF0B66","37D83BF0","A9BCAE53","DEBB9EC5","47B2CF7F","30B5FFE9","BDBDF21C","CABAC28A","53B39330","24B4A3A6","BAD03605","CDD70693","54DE5729","23D967BF","B3667A2E","C4614AB8","5D681B02","2A6F2B94","B40BBE37","C30C8EA1","5A05DF1B","2D02EF8D"];for(b=0,c=0,e=a.length,f=-1^f,d=0;e>d;d++)b=255&(f^a.charCodeAt(d)),c="0x"+g[b],f=f>>>8^c;return-1^f},countingChars:function(a,b){"use strict";return a=a.split(b),"object"==typeof a?a.length-1:0},htmlEncode:function(a){"use strict";var b=document.createElement("div");return b.appendChild(document.createTextNode(a)),a=b.innerHTML,b=void 0,a},mmdCSSclass:function(a,b){"use strict";var c;return-1!==a.indexOf("/")&&b!==!0?(c=a.split("/"),c=0===c[1].length?c[2].split("."):c[0].split("."),'class="mmd_'+c[c.length-2].replace(/[^\w\d]/g,"")+c[c.length-1]+'" '):""}};!function(a,b){"use strict";"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.returnExports=b()}(this,function(){"use strict";return micromarkdown});
+
+/* /micromarkdown */
\ No newline at end of file
diff --git a/akvo/rsr/static/scripts-src/project-main/project-main-report.js b/akvo/rsr/static/scripts-src/project-main/project-main-report.js
index 6998373ed2..3c9287bcc8 100644
--- a/akvo/rsr/static/scripts-src/project-main/project-main-report.js
+++ b/akvo/rsr/static/scripts-src/project-main/project-main-report.js
@@ -398,6 +398,13 @@ function renderReportTab() {
},
descriptions: function(proj) {
+ var projectPlanText = {__html: micromarkdown.parse(proj.project_plan)};
+ var goalsOverviewText = {__html: micromarkdown.parse(proj.goals_overview)};
+ var targetGroupText = {__html: micromarkdown.parse(proj.target_group)};
+ var backgroundText = {__html: micromarkdown.parse(proj.background)};
+ var currentStatusText = {__html: micromarkdown.parse(proj.current_status)};
+ var sustainabilityText = {__html: micromarkdown.parse(proj.sustainability)};
+
return (
React.DOM.div( {className:"row"},
React.DOM.div( {className:"col-sm-12"},
@@ -407,15 +414,15 @@ function renderReportTab() {
React.DOM.tbody(null,
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.project_plan),
- React.DOM.td(null, proj.project_plan)
+ React.DOM.td( {dangerouslySetInnerHTML:projectPlanText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.goals_overview),
- React.DOM.td(null, proj.goals_overview)
+ React.DOM.td( {dangerouslySetInnerHTML:goalsOverviewText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.target_group),
- React.DOM.td(null, proj.target_group)
+ React.DOM.td( {dangerouslySetInnerHTML:targetGroupText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.project_plan_summary),
@@ -423,15 +430,15 @@ function renderReportTab() {
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.background),
- React.DOM.td(null, proj.background)
+ React.DOM.td( {dangerouslySetInnerHTML:backgroundText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.current_status),
- React.DOM.td(null, proj.current_status)
+ React.DOM.td( {dangerouslySetInnerHTML:currentStatusText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.sustainability),
- React.DOM.td(null, proj.sustainability)
+ React.DOM.td( {dangerouslySetInnerHTML:sustainabilityText} )
),
React.DOM.tr(null,
React.DOM.th( {scope:"row"}, i18nReport.keywords),
@@ -630,9 +637,14 @@ var loadJS = function(url, implementationCode, location){
};
function loadAndRenderReact() {
+ function loadMarkdown() {
+ var markdownSrc = document.getElementById('markdown').src;
+ loadJS(markdownSrc, renderReportTab, document.body);
+ }
+
function loadReactDOM() {
var reactDOMSrc = document.getElementById('react-dom').src;
- loadJS(reactDOMSrc, renderReportTab, document.body);
+ loadJS(reactDOMSrc, loadMarkdown, document.body);
}
console.log('No React, load again.');
@@ -648,7 +660,7 @@ document.addEventListener('DOMContentLoaded', function() {
projectIdReport = JSON.parse(document.getElementById('default-values').innerHTML).project_id;
// Check if React is loaded
- if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined') {
+ if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && micromarkdown !== 'undefined') {
// Render React components
renderReportTab();
} else {
diff --git a/akvo/rsr/static/scripts-src/project-main/project-main-report.jsx b/akvo/rsr/static/scripts-src/project-main/project-main-report.jsx
index 7c7d76134f..7557973fff 100644
--- a/akvo/rsr/static/scripts-src/project-main/project-main-report.jsx
+++ b/akvo/rsr/static/scripts-src/project-main/project-main-report.jsx
@@ -398,6 +398,13 @@ function renderReportTab() {
},
descriptions: function(proj) {
+ var projectPlanText = {__html: micromarkdown.parse(proj.project_plan)};
+ var goalsOverviewText = {__html: micromarkdown.parse(proj.goals_overview)};
+ var targetGroupText = {__html: micromarkdown.parse(proj.target_group)};
+ var backgroundText = {__html: micromarkdown.parse(proj.background)};
+ var currentStatusText = {__html: micromarkdown.parse(proj.current_status)};
+ var sustainabilityText = {__html: micromarkdown.parse(proj.sustainability)};
+
return (
@@ -407,15 +414,15 @@ function renderReportTab() {
{i18nReport.project_plan} |
- {proj.project_plan} |
+ |
{i18nReport.goals_overview} |
- {proj.goals_overview} |
+ |
{i18nReport.target_group} |
- {proj.target_group} |
+ |
{i18nReport.project_plan_summary} |
@@ -423,15 +430,15 @@ function renderReportTab() {
{i18nReport.background} |
- {proj.background} |
+ |
{i18nReport.current_status} |
- {proj.current_status} |
+ |
{i18nReport.sustainability} |
- {proj.sustainability} |
+ |
{i18nReport.keywords} |
@@ -630,9 +637,14 @@ var loadJS = function(url, implementationCode, location){
};
function loadAndRenderReact() {
+ function loadMarkdown() {
+ var markdownSrc = document.getElementById('markdown').src;
+ loadJS(markdownSrc, renderReportTab, document.body);
+ }
+
function loadReactDOM() {
var reactDOMSrc = document.getElementById('react-dom').src;
- loadJS(reactDOMSrc, renderReportTab, document.body);
+ loadJS(reactDOMSrc, loadMarkdown, document.body);
}
console.log('No React, load again.');
@@ -648,7 +660,7 @@ document.addEventListener('DOMContentLoaded', function() {
projectIdReport = JSON.parse(document.getElementById('default-values').innerHTML).project_id;
// Check if React is loaded
- if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined') {
+ if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && micromarkdown !== 'undefined') {
// Render React components
renderReportTab();
} else {
diff --git a/akvo/rsr/static/scripts-src/project-main/project-main.js b/akvo/rsr/static/scripts-src/project-main/project-main.js
index 80280e5577..dacf5f8350 100755
--- a/akvo/rsr/static/scripts-src/project-main/project-main.js
+++ b/akvo/rsr/static/scripts-src/project-main/project-main.js
@@ -173,6 +173,8 @@ function renderReactComponents() {
panelStyle = {height: '0px'};
}
+ var htmlContent = {__html: micromarkdown.parse(this.props.content)};
+
return (
React.DOM.div( {className:panelClass},
React.DOM.div( {className:"panel-heading"},
@@ -183,9 +185,8 @@ function renderReactComponents() {
)
),
React.DOM.div( {className:panelCollapse, style:panelStyle},
- React.DOM.div( {className:"panel-body"},
- this.props.content
- )
+ React.DOM.div( {className:"panel-body",
+ dangerouslySetInnerHTML:htmlContent})
)
)
);
@@ -219,15 +220,6 @@ function renderReactComponents() {
});
},
- splitLines: function(text) {
- var i = 0;
- return text.match(/[^\r\n]+/g).map(function(line) {
- return (
- React.DOM.p( {key:i++}, line)
- );
- });
- },
-
render: function() {
var background = this.props.source.background || null,
current_status = this.props.source.current_status || null,
@@ -241,7 +233,7 @@ function renderReactComponents() {
background = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(background),
+ content: background,
panelClass: "background"
});
}
@@ -250,7 +242,7 @@ function renderReactComponents() {
current_status = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(current_status),
+ content: current_status,
panelClass: "current_status"
});
}
@@ -259,7 +251,7 @@ function renderReactComponents() {
goals_overview = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(goals_overview),
+ content: goals_overview,
panelClass: "goals_overview"
});
}
@@ -268,7 +260,7 @@ function renderReactComponents() {
project_plan = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(project_plan),
+ content: project_plan,
panelClass: "project_plan"
});
}
@@ -277,7 +269,7 @@ function renderReactComponents() {
sustainability = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(sustainability),
+ content: sustainability,
panelClass: "sustainability"
});
}
@@ -286,7 +278,7 @@ function renderReactComponents() {
target_group = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(target_group),
+ content: target_group,
panelClass: "target_group"
});
}
@@ -459,9 +451,14 @@ var loadJS = function(url, implementationCode, location){
};
function loadAndRenderReact() {
+ function loadMarkdown() {
+ var markdownSrc = document.getElementById('markdown').src;
+ loadJS(markdownSrc, renderReactComponents, document.body);
+ }
+
function loadReactBootstrap() {
var reactBootstrapSrc = document.getElementById('react-bootstrap').src;
- loadJS(reactBootstrapSrc, renderReactComponents, document.body);
+ loadJS(reactBootstrapSrc, loadMarkdown, document.body);
}
function loadReactDOM() {
@@ -486,7 +483,7 @@ document.addEventListener('DOMContentLoaded', function() {
readMoreOnClicks();
// Check if React is loaded
- if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && typeof ReactBootstrap !== 'undefined') {
+ if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && typeof ReactBootstrap !== 'undefined' && micromarkdown !== 'undefined') {
// Render React components
renderReactComponents();
} else {
diff --git a/akvo/rsr/static/scripts-src/project-main/project-main.jsx b/akvo/rsr/static/scripts-src/project-main/project-main.jsx
index 1c79042236..365e7d438f 100755
--- a/akvo/rsr/static/scripts-src/project-main/project-main.jsx
+++ b/akvo/rsr/static/scripts-src/project-main/project-main.jsx
@@ -173,6 +173,8 @@ function renderReactComponents() {
panelStyle = {height: '0px'};
}
+ var htmlContent = {__html: micromarkdown.parse(this.props.content)};
+
return (
@@ -183,9 +185,8 @@ function renderReactComponents() {
-
- {this.props.content}
-
+
);
@@ -219,15 +220,6 @@ function renderReactComponents() {
});
},
- splitLines: function(text) {
- var i = 0;
- return text.match(/[^\r\n]+/g).map(function(line) {
- return (
- {line}
- );
- });
- },
-
render: function() {
var background = this.props.source.background || null,
current_status = this.props.source.current_status || null,
@@ -241,7 +233,7 @@ function renderReactComponents() {
background = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(background),
+ content: background,
panelClass: "background"
});
}
@@ -250,7 +242,7 @@ function renderReactComponents() {
current_status = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(current_status),
+ content: current_status,
panelClass: "current_status"
});
}
@@ -259,7 +251,7 @@ function renderReactComponents() {
goals_overview = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(goals_overview),
+ content: goals_overview,
panelClass: "goals_overview"
});
}
@@ -268,7 +260,7 @@ function renderReactComponents() {
project_plan = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(project_plan),
+ content: project_plan,
panelClass: "project_plan"
});
}
@@ -277,7 +269,7 @@ function renderReactComponents() {
sustainability = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(sustainability),
+ content: sustainability,
panelClass: "sustainability"
});
}
@@ -286,7 +278,7 @@ function renderReactComponents() {
target_group = React.createElement(AccordionPanel, {
opened: this.state.opened,
changeOpened: this.changeOpened,
- content: this.splitLines(target_group),
+ content: target_group,
panelClass: "target_group"
});
}
@@ -459,9 +451,14 @@ var loadJS = function(url, implementationCode, location){
};
function loadAndRenderReact() {
+ function loadMarkdown() {
+ var markdownSrc = document.getElementById('markdown').src;
+ loadJS(markdownSrc, renderReactComponents, document.body);
+ }
+
function loadReactBootstrap() {
var reactBootstrapSrc = document.getElementById('react-bootstrap').src;
- loadJS(reactBootstrapSrc, renderReactComponents, document.body);
+ loadJS(reactBootstrapSrc, loadMarkdown, document.body);
}
function loadReactDOM() {
@@ -486,7 +483,7 @@ document.addEventListener('DOMContentLoaded', function() {
readMoreOnClicks();
// Check if React is loaded
- if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && typeof ReactBootstrap !== 'undefined') {
+ if (typeof React !== 'undefined' && typeof ReactDOM !== 'undefined' && typeof ReactBootstrap !== 'undefined' && micromarkdown !== 'undefined') {
// Render React components
renderReactComponents();
} else {
diff --git a/akvo/templates/project_main.html b/akvo/templates/project_main.html
index 388ee4dcb1..2abfe237a8 100644
--- a/akvo/templates/project_main.html
+++ b/akvo/templates/project_main.html
@@ -41,6 +41,9 @@
+ {# Markdown #}
+
+
{# Descriptions #}