580 lines
16 KiB
JavaScript
580 lines
16 KiB
JavaScript
/**
|
|
* macro rendering title
|
|
*/
|
|
function title_macro(param) {
|
|
if (param.as == "editor")
|
|
Html.input(this.createInputParam("title", param));
|
|
else {
|
|
if (param && param.linkto) {
|
|
if (param.linkto == "main")
|
|
param.linkto = "";
|
|
Html.openLink({href: this.href(param.linkto)});
|
|
if (this.title && this.title.trim())
|
|
res.write(stripTags(this.title));
|
|
else
|
|
res.write("<em>[untitled]</em>");
|
|
Html.closeLink();
|
|
} else
|
|
res.write(this.title);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering alias
|
|
*/
|
|
function alias_macro(param) {
|
|
if (param.as == "editor")
|
|
Html.input(this.createInputParam("alias", param));
|
|
else
|
|
res.write(this.alias);
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering tagline
|
|
*/
|
|
function tagline_macro(param) {
|
|
if (param.as == "editor")
|
|
Html.input(this.preferences.createInputParam("tagline", param));
|
|
else if (this.preferences.getProperty("tagline"))
|
|
res.write(stripTags(this.preferences.getProperty("tagline")));
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering email
|
|
*/
|
|
function email_macro(param) {
|
|
if (param.as == "editor")
|
|
Html.input(this.createInputParam("email", param));
|
|
else
|
|
res.write(this.email);
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering lastupdate
|
|
*/
|
|
function lastupdate_macro(param) {
|
|
if (this.lastupdate)
|
|
res.write(formatTimestamp(this.lastupdate, param.format));
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering online-status
|
|
*/
|
|
function online_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.createCheckBoxParam("online", param);
|
|
if (req.data.save && !req.data.online)
|
|
delete inputParam.checked;
|
|
Html.checkBox(inputParam);
|
|
} else if (this.online)
|
|
res.write(param.yes ? param.yes : "yes");
|
|
else
|
|
res.write(param.no ? param.no : "no");
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering discussion-flag
|
|
*/
|
|
function hasdiscussions_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.preferences.createCheckBoxParam("discussions", param);
|
|
if (req.data.save && !req.data.preferences_discussions)
|
|
delete inputParam.checked;
|
|
Html.checkBox(inputParam);
|
|
} else
|
|
res.write(this.preferences.getProperty("discussions") ? "yes" : "no");
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering usercontrib-flag
|
|
*/
|
|
function usermaycontrib_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.preferences.createCheckBoxParam("usercontrib", param);
|
|
if (req.data.save && !req.data.preferences_usercontrib)
|
|
delete inputParam.checked;
|
|
Html.checkBox(inputParam);
|
|
} else
|
|
res.write(this.preferences.getProperty("usercontrib") ? "yes" : "no");
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering nr. of days to show on site-fontpage
|
|
*/
|
|
function showdays_macro(param) {
|
|
if (param.as == "editor")
|
|
Html.input(this.preferences.createInputParam("days", param));
|
|
else
|
|
res.write(this.preferences.getProperty("days"));
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering archive-flag
|
|
*/
|
|
function showarchive_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.preferences.createCheckBoxParam("archive", param);
|
|
if (req.data.save && !req.data.preferences_archive)
|
|
delete inputParam.checked;
|
|
Html.checkBox(inputParam);
|
|
} else
|
|
res.write(this.preferences.getProperty("archive") ? "yes" : "no");
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering enableping-flag
|
|
*/
|
|
function enableping_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.createCheckBoxParam("enableping", param);
|
|
if (req.data.save && !req.data.enableping)
|
|
delete inputParam.checked;
|
|
Html.checkBox(inputParam);
|
|
} else
|
|
res.write(this.enableping ? "yes" : "no");
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering default longdateformat
|
|
*/
|
|
function longdateformat_macro(param) {
|
|
if (param.as == "chooser")
|
|
renderDateformatChooser("longdateformat",
|
|
this.getLocale(),
|
|
this.preferences.getProperty("longdateformat"));
|
|
else if (param.as == "editor")
|
|
Html.input(this.preferences.createInputParam("longdateformat", param));
|
|
else
|
|
res.write(this.preferences.getProperty("longdateformat"));
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering default shortdateformat
|
|
*/
|
|
function shortdateformat_macro(param) {
|
|
if (param.as == "chooser")
|
|
renderDateformatChooser("shortdateformat",
|
|
this.getLocale(),
|
|
this.preferences.getProperty("shortdateformat"));
|
|
else if (param.as == "editor")
|
|
Html.input(this.preferences.createInputParam("shortdateformat", param));
|
|
else
|
|
res.write(this.preferences.getProperty("shortdateformat"));
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering loginStatus of user
|
|
* valid params: - loginSkin
|
|
* - logoutSkin
|
|
*/
|
|
function loginstatus_macro(param) {
|
|
if (session.user)
|
|
this.members.renderSkin("statusloggedin");
|
|
else if (req.action != "login")
|
|
this.members.renderSkin("statusloggedout");
|
|
}
|
|
|
|
|
|
/**
|
|
* macro rendering two different navigation-skins
|
|
* depending on user-status & rights
|
|
*/
|
|
function navigation_macro(param) {
|
|
if (!param["for"] || param["for"] == "users") {
|
|
// FIXME: this is left for backwards-compatibility
|
|
// sometime in the future we'll get rid of the usernavigation.skin
|
|
res.write("... ");
|
|
Html.link({href: "http://project.antville.org/project/stories/146"}, "<strong>README</strong>");
|
|
Html.tag("br");
|
|
Html.tag("br");
|
|
this.renderSkin("usernavigation");
|
|
}
|
|
if (!session.user)
|
|
return;
|
|
switch (param["for"]) {
|
|
case "contributors" :
|
|
if (session.user.sysadmin || this.preferences.getProperty("usercontrib") || req.data.memberlevel >= CONTRIBUTOR)
|
|
this.renderSkin("contribnavigation");
|
|
break;
|
|
case "admins" :
|
|
if (session.user.sysadmin || req.data.memberlevel >= ADMIN)
|
|
this.renderSkin("adminnavigation");
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* macro renders a calendar
|
|
* version 2
|
|
*/
|
|
function calendar_macro(param) {
|
|
// do nothing if there is not a single story :-))
|
|
// or if archive of this site is disabled
|
|
if (!this.allstories.size() || !this.preferences.getProperty("archive"))
|
|
return;
|
|
// define variables needed in this function
|
|
var calParam = new Object();
|
|
var dayParam = new Object();
|
|
var weekParam = new Object();
|
|
res.push();
|
|
|
|
// create new calendar-object
|
|
var cal = java.util.Calendar.getInstance(this.getTimeZone(), this.getLocale());
|
|
var symbols = this.getDateSymbols();
|
|
|
|
// render header-row of calendar
|
|
var firstDayOfWeek = cal.getFirstDayOfWeek();
|
|
var weekdays = symbols.getShortWeekdays();
|
|
res.push();
|
|
for (var i=0;i<7;i++) {
|
|
dayParam.day = weekdays[(i+firstDayOfWeek-1)%7+1];
|
|
this.renderSkin("calendardayheader", dayParam);
|
|
}
|
|
weekParam.week = res.pop();
|
|
this.renderSkin("calendarweek", weekParam);
|
|
|
|
cal.set(java.util.Calendar.DATE, 1);
|
|
// check whether there's a day or a story in path
|
|
// if so, use it to determine the month to render
|
|
if (path.story)
|
|
var today = path.story.day.toString();
|
|
else if (path.day && path.day._prototype == "day")
|
|
var today = path.day.groupname.toString();
|
|
if (today) {
|
|
// instead of using String.toDate
|
|
// we do it manually here to avoid that a day like 20021001
|
|
// would be changed to 20020930 in some cases
|
|
cal.set(java.util.Calendar.YEAR, parseInt(today.substring(0, 4), 10));
|
|
cal.set(java.util.Calendar.MONTH, parseInt(today.substring(4, 6), 10)-1);
|
|
}
|
|
// nr. of empty days in rendered calendar before the first day of month appears
|
|
var pre = (7-firstDayOfWeek+cal.get(java.util.Calendar.DAY_OF_WEEK)) % 7;
|
|
var days = cal.getActualMaximum(java.util.Calendar.DATE);
|
|
var weeks = Math.ceil((pre + days) / 7);
|
|
var daycnt = 1;
|
|
|
|
var monthNames = symbols.getMonths();
|
|
calParam.month = monthNames[cal.get(java.util.Calendar.MONTH)];
|
|
calParam.year = cal.get(java.util.Calendar.YEAR);
|
|
|
|
// pre-render the year and month so we only have to append the days as we loop
|
|
var currMonth = formatTimestamp(new Date(cal.getTime().getTime()), "yyyyMM");
|
|
// remember the index of the first and last days within this month.
|
|
// this is needed to optimize previous and next month links.
|
|
var lastDayIndex = 9999999;
|
|
var firstDayIndex = -1;
|
|
|
|
for (var i=0;i<weeks;i++) {
|
|
res.push();
|
|
for (var j=0;j<7;j++) {
|
|
dayParam.skin = "calendarday";
|
|
if ((i == 0 && j < pre) || daycnt > days)
|
|
dayParam.day = " ";
|
|
else {
|
|
var currGroupname = currMonth+daycnt.format("00");
|
|
var linkText = daycnt < 10 ? " " + daycnt + " " : daycnt.toString();
|
|
var currGroup = this.get(currGroupname);
|
|
if (currGroup) {
|
|
var idx = this.contains(currGroup);
|
|
if (idx > -1) {
|
|
if (idx > firstDayIndex)
|
|
firstDayIndex = idx;
|
|
if (idx < lastDayIndex)
|
|
lastDayIndex = idx;
|
|
}
|
|
dayParam.day = Html.linkAsString({href: currGroup.href()}, linkText);
|
|
} else {
|
|
dayParam.day = linkText;
|
|
}
|
|
if (currGroupname == today)
|
|
dayParam.skin = "calendarselday";
|
|
daycnt++;
|
|
}
|
|
this.renderSkin(dayParam.skin, dayParam);
|
|
}
|
|
weekParam.week = res.pop();
|
|
this.renderSkin("calendarweek", weekParam);
|
|
}
|
|
// set day to last day of month and try to render next month
|
|
// check what the last day of the month is
|
|
calParam.back = this.renderLinkToPrevMonth(firstDayIndex, currMonth + "01", monthNames);
|
|
calParam.forward = this.renderLinkToNextMonth(lastDayIndex, currMonth + "31", monthNames);
|
|
calParam.calendar = res.pop();
|
|
this.renderSkin("calendar", calParam);
|
|
}
|
|
|
|
|
|
/**
|
|
* macro renders age
|
|
*/
|
|
function age_macro(param) {
|
|
res.write(Math.floor((new Date() - this.createtime) / ONEDAY));
|
|
}
|
|
|
|
|
|
/**
|
|
* macro left for backwards-compatibility
|
|
* calls global image_macro()
|
|
*/
|
|
function image_macro(param) {
|
|
image_macro(param);
|
|
}
|
|
|
|
|
|
/**
|
|
* macro left for backwards-compatibility
|
|
* calls global thumbnail_macro()
|
|
*/
|
|
function thumbnail_macro(param) {
|
|
thumbnail_macro(param);
|
|
}
|
|
|
|
|
|
/**
|
|
* macro renders the number of members of this site
|
|
*/
|
|
function membercounter_macro(param) {
|
|
res.write(this.members.size());
|
|
}
|
|
|
|
|
|
/**
|
|
* macro renders a list of recently added/updated stories/comments
|
|
* of this site
|
|
*/
|
|
function history_macro(param) {
|
|
try {
|
|
this.checkView(session.user, req.data.memberlevel);
|
|
} catch (deny) {
|
|
return;
|
|
}
|
|
if (!param.show)
|
|
param.show = 5;
|
|
var cnt = 0;
|
|
var i = 0;
|
|
this.lastmod.prefetchChildren(0, parseInt(param.show, 10));
|
|
while (cnt < param.show && this.lastmod.get(i)) {
|
|
var item = this.lastmod.get(i++);
|
|
if (!item.story || (item.story.online && item.story.discussions &&
|
|
item.site.preferences.getProperty("discussions"))) {
|
|
item.renderSkin("historyview");
|
|
cnt++;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* macro renders a list of available locales as dropdown
|
|
*/
|
|
function localechooser_macro(param) {
|
|
renderLocaleChooser(this.getLocale());
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* macro renders a list of available time zones as dropdown
|
|
*/
|
|
function timezonechooser_macro(param) {
|
|
renderTimeZoneChooser(this.getTimeZone());
|
|
}
|
|
|
|
|
|
/**
|
|
* renders a list of most read pages, ie. a link
|
|
* to a story together with the read counter et al.
|
|
*/
|
|
function listMostRead_macro() {
|
|
var param = new Object();
|
|
var size = this.mostread.size();
|
|
for (var i=0; i<size; i++) {
|
|
var s = this.mostread.get(i);
|
|
param.reads = s.reads;
|
|
param.rank = i+1;
|
|
s.renderSkin("mostread", param);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* renders a list of referrers, ie. a link
|
|
* to a url together with the read counter et al.
|
|
*/
|
|
function listReferrers_macro() {
|
|
var c = getDBConnection("antville");
|
|
var dbError = c.getLastError();
|
|
if (dbError)
|
|
return getMessage("error.database", dbError);
|
|
// we're doing this with direct db access here
|
|
// (there's no need to do it with prototypes):
|
|
var d = new Date();
|
|
d.setDate(d.getDate()-1); // 24 hours ago
|
|
var query = "select ACCESSLOG_REFERRER, count(*) as \"COUNT\" from AV_ACCESSLOG " +
|
|
"where ACCESSLOG_F_SITE = " + this._id + " and ACCESSLOG_DATE > {ts '" +
|
|
d.format("yyyy-MM-dd HH:mm:ss") + "'} group by ACCESSLOG_REFERRER "+
|
|
"order by \"COUNT\" desc, ACCESSLOG_REFERRER asc;";
|
|
var rows = c.executeRetrieval(query);
|
|
var dbError = c.getLastError();
|
|
if (dbError)
|
|
return getMessage("error.database", dbError);
|
|
var skinParam = new Object();
|
|
var referrer;
|
|
while (rows.next()) {
|
|
skinParam.count = rows.getColumnItem("COUNT");
|
|
referrer = rows.getColumnItem("ACCESSLOG_REFERRER");
|
|
skinParam.referrer = encode(referrer);
|
|
skinParam.text = encode(referrer.length > 50 ? referrer.substring(0, 50) + "..." : referrer);
|
|
this.renderSkin("referrerItem", skinParam);
|
|
}
|
|
rows.release();
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* renders the xml button for use
|
|
* when referring to an rss feed
|
|
*/
|
|
function xmlbutton_macro(param) {
|
|
param.linkto = this.href("rss");
|
|
DefaultImages.render("xmlbutton", param);
|
|
}
|
|
|
|
|
|
/**
|
|
* renders the searchbox
|
|
*/
|
|
function searchbox_macro(param) {
|
|
this.renderSkin("searchbox");
|
|
}
|
|
|
|
|
|
/**
|
|
* function renders the months of the archive
|
|
*/
|
|
function monthlist_macro(param) {
|
|
if (!this.stories.size() || !this.preferences.getProperty("archive"))
|
|
return;
|
|
var size = param.limit ? Math.min(this.size(), param.limit) : this.size();
|
|
for (var i=0;i<size;i++) {
|
|
var curr = this.get(i);
|
|
var next = this.get(i+1);
|
|
if (!next || next.groupname.substring(0, 6) < curr.groupname.substring(0, 6)) {
|
|
res.write(param.itemprefix);
|
|
Html.openLink({href: curr.href()});
|
|
var ts = curr.groupname.substring(0, 6).toDate("yyyyMM", this.getTimeZone());
|
|
res.write(formatTimestamp(ts, param.format ? param.format : "MMMM yyyy"));
|
|
Html.closeLink();
|
|
res.write(param.itemsuffix);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* wrapper-macro for topiclist
|
|
*/
|
|
function topiclist_macro(param) {
|
|
this.topics.topiclist_macro(param);
|
|
}
|
|
|
|
/**
|
|
* wrapper-macro for imagelist
|
|
*/
|
|
function imagelist_macro(param) {
|
|
this.images.imagelist_macro(param);
|
|
}
|
|
|
|
/**
|
|
* proxy-macro for layout chooser
|
|
*/
|
|
function layoutchooser_macro(param) {
|
|
if (this.layout)
|
|
param.selected = this.layout.alias;
|
|
this.layouts.layoutchooser_macro(param);
|
|
}
|
|
|
|
/**
|
|
* macro rendering recipients for email notification
|
|
* param.event: storycreate/commentcreate/textupdate/upload
|
|
* please add some error message for undefined param.event
|
|
*/
|
|
function notify_macro(param) {
|
|
if (param.as == "editor") {
|
|
var options = new Array("Don't notify anyone", "Notify content managers and admins", "Notify contributors and above");
|
|
var pref = this.preferences.getProperty("notify_" + param.event);
|
|
Html.dropDown({name: "notify_" + param.event}, options, pref);
|
|
} else {
|
|
if (pref == 2)
|
|
res.write("Notify contributors");
|
|
else if (pref == 1)
|
|
res.write("Notify content managers");
|
|
else
|
|
res.write("Don't notify anyone");
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* macro rendering notification settings if enabled
|
|
*/
|
|
function notification_macro(param) {
|
|
if (this.isNotificationEnabled())
|
|
this.renderSkin("notification");
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* render generic preference editor or value
|
|
*/
|
|
function preferences_macro(param) {
|
|
if (param.as == "editor") {
|
|
var inputParam = this.preferences.createInputParam(param.name, param);
|
|
delete inputParam.part;
|
|
if (param.cols || param.rows)
|
|
Html.textArea(inputParam);
|
|
else
|
|
Html.input(inputParam);
|
|
} else
|
|
res.write(this.preferences.getProperty(param.name));
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* output spamfilter data appropriate
|
|
* for client-side javascript code
|
|
*/
|
|
function spamfilter_macro(param) {
|
|
var str = this.preferences.getProperty("spamfilter");
|
|
var items = str.replace(/\n/g, "").split("\r");
|
|
for (var i in items) {
|
|
res.write('"');
|
|
res.write(items[i]);
|
|
res.write('"');
|
|
if (i < items.length-1)
|
|
res.write(",");
|
|
}
|
|
return;
|
|
}
|