Initial revision

This commit is contained in:
Robert Gaggl 2001-06-18 08:57:33 +00:00
parent 1ba4e8011b
commit bbfcb3d4f4
104 changed files with 3100 additions and 0 deletions

138
antville.sql Normal file
View file

@ -0,0 +1,138 @@
use antville ;
#----------------------------
# Table structure for COMMENT
#----------------------------
create table COMMENT (
ID mediumint(9) not null default '0',
WEBLOG_ID mediumint(9),
STORY_ID mediumint(9),
PARENT_ID mediumint(9) default '0',
TITLE mediumtext,
TEXT mediumtext,
AUTHOR mediumint(9),
CREATETIME datetime,
MODIFYTIME datetime,
ISONLINE tinyint(1),
IPADDRESS varchar(20),
unique ID (ID));
#----------------------------
# No records for table COMMENT
#----------------------------
#----------------------------
# Table structure for IMAGE
#----------------------------
create table IMAGE (
ID mediumint(9) not null default '0',
WEBLOG_ID mediumint(9),
ALIAS tinytext,
FILENAME tinytext,
FILEEXT tinytext,
WIDTH mediumint(9),
HEIGHT mediumint(9),
ALTTEXT tinytext,
CREATETIME datetime,
CREATOR mediumint(9),
MODIFYTIME datetime,
MODIFIER mediumint(9),
unique ID (ID));
#----------------------------
# No records for table IMAGE
#----------------------------
#----------------------------
# Table structure for SKIN
#----------------------------
create table SKIN (
ID mediumint(9) not null default '0',
WEBLOG_ID mediumint(9),
PROTO tinytext,
NAME tinytext,
SOURCE mediumtext,
CREATOR mediumint(9),
CREATETIME datetime,
MODIFYTIME datetime,
unique ID (ID));
#----------------------------
# No records for table SKIN
#----------------------------
#----------------------------
# Table structure for STORY
#----------------------------
create table STORY (
ID mediumint(9) not null default '0',
WEBLOG_ID mediumint(9),
DAY varchar(10),
TITLE mediumtext,
TEXT mediumtext,
ISONLINE tinyint(1),
AUTHOR mediumint(9),
CREATETIME datetime,
MODIFYTIME datetime,
unique ID (ID));
#----------------------------
# No records for table STORY
#----------------------------
#----------------------------
# Table structure for USER
#----------------------------
create table USER (
ID mediumint(9) not null default '0',
WEBLOG_ID mediumint(9),
USERNAME tinytext,
PASSWORD tinytext,
EMAIL tinytext,
DESCRIPTION mediumtext,
URL tinytext,
REGISTERED datetime,
LASTVISIT datetime,
ISBLOCKED tinyint(1),
unique ID (ID));
#----------------------------
# No records for table USER
#----------------------------
#----------------------------
# Table structure for WEBLOG
#----------------------------
create table WEBLOG (
ID mediumint(9) not null default '0',
OWNER_ID mediumint(9),
TITLE tinytext,
ALIAS tinytext,
TAGLINE tinytext,
BIRTHDATE datetime,
BGCOLOR varchar(6),
TEXTFONT tinytext,
TEXTCOLOR varchar(6),
TEXTSIZE varchar(4),
LINKCOLOR varchar(6),
ALINKCOLOR varchar(6),
VLINKCOLOR varchar(6),
TITLEFONT tinytext,
TITLECOLOR varchar(6),
TITLESIZE varchar(4),
ISONLINE tinyint(1),
ISBLOCKED tinyint(1),
LASTUPDATE datetime,
HASDISCUSSIONS tinyint(1),
SHOWDAYS tinyint(4),
SHOWARCHIVE tinyint(1),
CREATETIME datetime,
CREATOR mediumint(9),
MODIFYTIME datetime,
MODIFIER mediumint(9),
unique ID (ID));
#----------------------------
# No records for table WEBLOG
#----------------------------

17
code/Comment/delete.hac Normal file
View file

@ -0,0 +1,17 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions("delete");
if (req.data.submit == "delete")
if (this.parent)
this.parent.deleteComment(this);
else
this.story.deleteComment(this);
else if (req.data.submit == "cancel")
res.redirect(this.story.href("main"));
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("delete");

4
code/Comment/delete.skin Normal file
View file

@ -0,0 +1,4 @@
<FORM METHOD="POST">
<P>Warning! You are about to delete the a comment from <B><% this.author %></B>! Be aware of the fact that there is no "undo", so if you klick on delete here the comment will be gone forever!</P>
<P><% this.input type="button" value="delete" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

13
code/Comment/edit.hac Normal file
View file

@ -0,0 +1,13 @@
// check if user has right to edit this comment
this.checkPermissions();
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
if (req.data.text)
this.updateComment();
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("edit");

5
code/Comment/edit.skin Normal file
View file

@ -0,0 +1,5 @@
<FORM METHOD="POST">
<P>Title: <% this.title as="editor" %></P>
<P>Text: <% this.text as="editor" %></P>
<% this.input type="button" value="save" %>
</FORM>

View file

@ -0,0 +1,8 @@
/**
* function filters comments
* only toplevel-comments should appear as subnodes of story
*/
function filter() {
this.subnodeRelation = "WHERE PARENT_ID = " + this.__id__ + " ORDER BY CREATETIME asc";
}

132
code/Comment/macros.js Normal file
View file

@ -0,0 +1,132 @@
/**
* macro rendering title of comment
*/
function title_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("title",param));
else
res.write(this.title);
renderSuffix(param);
}
/**
* macro rendering text of comment
*/
function text_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputTextarea(this.createInputParam("text",param));
else {
var text = createSkin(format(this.text));
this.renderSkin(text);
}
renderSuffix(param);
}
/**
* macro renders author of comment
*/
function author_macro(param) {
renderPrefix(param);
if (this.author.url) {
var linkParam = new HopObject();
linkParam.to = this.author.url;
this.openLink(linkParam);
res.write(this.author.name);
this.closeLink();
} else
res.write(this.author.name);
renderSuffix(param);
}
/**
* macro renders createtime of comment
*/
function createtime_macro(param) {
renderPrefix(param);
res.write(param.format ? this.createtime.format(param.format) : this.createtime.format());
renderSuffix(param);
}
/**
* macro renders a link for editing a posting
* if user == author of posting
*/
function editlink_macro(param) {
if (this.weblog.hasDiscussions() && this.author == user && path[path.length-1] != this) {
renderPrefix(param);
var linkParam = new HopObject();
linkParam.linkto = "edit";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "edit");
else
this.renderImage(param);
this.closeLink();
renderSuffix(param);
}
}
/**
* macro renders a link to delete the comment
* if user == weblog-owner
*/
function deletelink_macro(param) {
if (this.weblog.hasDiscussions()) {
if (this.weblog.owner == user && path[path.length-1] != this) {
renderPrefix(param);
var linkParam = new HopObject();
linkParam.linkto = "delete";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "delete");
else
this.renderImage(param);
this.closeLink();
}
renderSuffix(param);
}
}
/**
* macro renders a link to reply to a comment
*/
function replylink_macro(param) {
if (this.weblog.hasDiscussions() && user.uid && !user.isBlocked() && path[path.length-1] != this) {
renderPrefix(param);
var linkParam = new HopObject();
linkParam.linkto = "reply";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "reply");
else
this.renderImage(param);
this.closeLink();
renderSuffix(param);
}
}
/**
* macro renders replies to this comment
*/
function replies_macro(param) {
if (this.weblog.hasDiscussions()) {
this.filter();
if (this.count()) {
renderPrefix(param);
for (var i=0;i<this.size();i++)
this.get(i).renderSkin("reply");
renderSuffix(param);
}
}
}

View file

@ -0,0 +1,45 @@
/**
* function evaluates changes to posting
*/
function updateComment() {
if (this.author == user) {
this.title = req.data.title;
this.text = req.data.text;
this.modifytime = new Date();
res.message = "Changes were saved successfully!";
} else
res.message = "Sorry, you're not allowed to edit a posting of somebody else!";
res.redirect(this.story.href());
}
/**
* function adds a comment to a comment ...
*/
function addComment() {
var r = new comment();
if (req.data.text) {
r.text = req.data.text;
r.title = req.data.title;
r.author = user;
r.createtime = new Date();
r.weblog = this.weblog;
r.story = this.story;
r.parent = this;
this.add(r);
res.redirect(this.story.href());
}
return (r);
}
/**
* function deletes a comment
*/
function deleteComment(currComment) {
currComment.setParent(this);
this.remove(currComment);
res.message = "The comment was deleted successfully!";
res.redirect(this.story.href());
}

12
code/Comment/reply.hac Normal file
View file

@ -0,0 +1,12 @@
if (this.weblog.hasDiscussions()) {
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
var r = this.addComment();
res.head = this.story.weblog.renderSkinAsString("style");
res.body = this.story.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("toplevel");
res.body += r.renderSkinAsString("edit");
} else
res.redirect(this.story.href());

4
code/Comment/reply.skin Normal file
View file

@ -0,0 +1,4 @@
<BLOCKQUOTE><B><% this.title %></B><BR>
<I><% this.author %><% this.createtime format="EEEE, dd.MM.yyyy HH:mm" prefix=",&nbsp;am&nbsp;" %></I><BR>
<% this.text %><BR>
<% this.editlink suffix="&nbsp;&nbsp;" %><% this.deletelink %></BLOCKQUOTE>

View file

@ -0,0 +1,20 @@
/**
* function checks if user has permissions to edit/delete a posting
*/
function checkPermissions(action) {
if (action == "delete") {
if (this.weblog.owner != user) {
res.message = "This is not your weblog, so you can't delete any postings!";
res.redirect(this.story.href());
}
return true;
} else {
if (this.author != user) {
res.message = "Sorry, you're not allowed to edit a posting of somebody else!";
res.redirect(this.story.href());
} else if (!this.weblog.hasDiscussions())
res.redirect(this.story.href());
return true;
}
}

View file

@ -0,0 +1,6 @@
<P><B><% this.title %></B><BR>
<I><% this.author %><% this.createtime format="EEEE, dd.MM.yyyy HH:mm" prefix=",&nbsp;am&nbsp;" %></I><BR>
<% this.text %><BR>
<% this.replylink text="reply to this comment ..." suffix="&nbsp;&nbsp;" %><% this.editlink suffix="&nbsp;&nbsp;" %><% this.deletelink %></P>
<% this.replies %>

View file

@ -0,0 +1,16 @@
_datasource=antville
_tablename=COMMENT
_subnodes=<comment.PARENT_ID
_subnodes.order=CREATETIME
_id=ID
weblog=WEBLOG_ID>weblog.ID
story=STORY_ID>story.ID
parent=PARENT_ID>comment.ID
title=TITLE
text=TEXT
author=AUTHOR>user.ID
createtime=CREATETIME
modifytime=MODIFYTIME
online=ISONLINE
ipaddress=IPADDRESS

12
code/Global/main.skin Normal file
View file

@ -0,0 +1,12 @@
<HTML>
<HEAD>
<TITLE><% response.title %></TITLE>
<% response.head %>
</HEAD>
<BODY>
<% response.body %>
</BODY>
</HTML>

View file

@ -0,0 +1,48 @@
/**
* check if email-adress is syntactically correct
*/
function checkEmail(address) {
var m = new Mail();
m.addTo(address);
if (m.status)
return false;
return true;
}
/**
* function checks if req.data.date[Year|Month|Date|Hours|Minutes] is valid
* if correct, creates dateobject and returns it
* otherwise false
*/
function checkDate() {
if (req.data.dateYear && req.data.dateMonth && req.data.dateDate && req.data.dateHours && req.data.dateMinutes) {
var ts = new Date();
ts.setYear(parseInt(req.data.dateYear));
ts.setMonth(parseInt(req.data.dateMonth));
ts.setDate(parseInt(req.data.dateDate));
ts.setHours(parseInt(req.data.dateHours));
ts.setMinutes(parseInt(req.data.dateMinutes));
ts.setSeconds(0);
return (ts);
} else
return false;
}
/**
* scheduler, basically doin' nothing
*/
function scheduler() {
return;
}
/**
* onStart-function, basically doin' nothing
*/
function onStart() {
return;
}

View file

@ -0,0 +1,36 @@
/**
* renders prefix if it's given
*/
function renderPrefix(param) {
if (param.prefix)
res.write(param.prefix);
return;
}
/**
* renders sufffix if it's given
*/
function renderSuffix(param) {
if (param.suffix)
res.write(param.suffix);
return;
}
/**
* returns name of action file the user has called
* Input params: none
* returns: string (= name of .hac-file)
*/
function getActionName() {
// return name of current action executed by user
var rPath = req.path.split("/");
if (path[path.length-1].__id__ == rPath[rPath.length-1] || path[path.length-1].__name__ == rPath[rPath.length-1])
return "main";
else
return(rPath[rPath.length -1]);
}

83
code/HopObject/macros.js Normal file
View file

@ -0,0 +1,83 @@
/**
* macro rendering a skin
* valid parameters: - prefix
* - suffix
* - name of skin
*/
function skin_macro(param) {
renderPrefix(param);
if (param.name)
this.renderSkin(param.name);
renderSuffix(param);
}
/**
* creates a <FORM ... tag
*/
function form_macro(param) {
if (param) {
renderPrefix(param);
res.write("<FORM METHOD=\"");
if (param.method == "GET")
res.write("GET\" ");
else
res.write("POST\" ");
res.write("ACTION=\"" + this.href(param.action ? param.action : "") + "\"");
if (param.enctype)
res.write(" ENCTYPE=\"" + param.enctype + "\">");
else
res.write(">");
renderSuffix(param);
}
}
/**
* macro creates a link by using the renderFunctions
* openLink() and closeLink()
*/
function link_macro(param) {
renderPrefix(param);
this.openLink(param);
res.write(param.text);
this.closeLink();
renderSuffix(param);
}
/**
* macro renders a form-input
* used mostly for those inputs that have no initial value
* i.e. in register.skin
*/
function input_macro(param) {
renderPrefix(param);
if (param.type == "textarea") {
var inputParam = new HopObject();
for (var i in param)
inputParam[i] = param[i];
inputParam.value = param.name ? req.data[param.name] : null;
this.renderInputTextarea(inputParam);
} else if (param.type == "checkbox") {
} else if (param.type == "button") {
this.renderInputButton(param);
} else if (param.type == "password") {
this.renderInputPassword(param);
} else if (param.type == "file") {
this.renderInputFile(param);
} else {
var inputParam = new HopObject();
for (var i in param)
inputParam[i] = param[i];
inputParam.value = param.name ? req.data[param.name] : null;
this.renderInputText(inputParam);
}
renderSuffix(param);
}

View file

@ -0,0 +1,86 @@
/**
* renders single dropdown
* input values: current Timestamp
*/
function createDDparam(prefix,ts,dropFormat) {
var ddParam = new HopObject();
if (dropFormat == "dd") {
ddParam.name = prefix + "Date";
ddParam.firstOption = "Day";
ddParam.currValue = ts ? ts.getDate() : null;
ddParam.start = 1;
ddParam.end = 31;
} else if (dropFormat == "MM") {
ddParam.name = prefix + "Month";
ddParam.firstOption = "Month";
ddParam.currValue = ts ? ts.getMonth() : null;
ddParam.start = 1;
ddParam.end = 12;
ddParam.valueOffset = -1;
} else if (dropFormat == "yyyy") {
ddParam.name = prefix + "Year";
ddParam.firstOption = "Year";
ddParam.currValue = ts ? ts.getFullYear() : null;
ddParam.start = 2000;
ddParam.end = 2010;
} else if (dropFormat == "HH") {
ddParam.name = prefix + "Hours";
ddParam.firstOption = "Hour";
ddParam.currValue = ts ? ts.getHours() : null;
ddParam.start = 0;
ddParam.end = 23;
} else if (dropFormat == "mm") {
ddParam.name = prefix + "Minutes";
ddParam.firstOption = "Minute";
ddParam.currValue = ts ? ts.getMinutes() : null;
ddParam.start = 0;
ddParam.end = 59;
} else if (dropFormat == "ss") {
ddParam.name = prefix + "Seconds";
ddParam.firstOption = "Second";
ddParam.currValue = ts ? ts.getSeconds() : null;
ddParam.start = 0;
ddParam.end = 59;
}
this.createDDOptions(ddParam);
return;
}
/**
* function creates array for rendering options
*/
function createDDOptions(ddParam) {
if (ddParam.firstOption) {
var option = new HopObject()
option.name = ddParam.firstOption;
option.value = "";
ddParam.add(option);
}
for (var i=ddParam.start;i<=ddParam.end;i++) {
var option = new HopObject();
option.name = (i<10 ? "0" + i : i);
option.value = (ddParam.valueOffset ? i+ddParam.valueOffset : i);
option.selected = (ddParam.currValue == option.value ? true : false);
ddParam.add(option);
}
this.chooser(ddParam);
}
/**
* creates parameter-object that will be passed to
* function that renders the input
*/
function createInputParam(propName,param) {
var inputParam = new HopObject();
inputParam.name = propName;
for (var i in param)
inputParam[i] = param[i];
inputParam.value = this[propName];
return (inputParam);
}

View file

@ -0,0 +1,185 @@
/**
* renders a textarea
* input: - parameter object
*/
function renderInputTextarea(param) {
if (param) {
res.write("<TEXTAREA NAME=\"" + param.name + "\"");
res.write(" ROWS=\"");
res.write(param.height ? param.height : "5");
res.write("\" COLS=\"");
res.write(param.width ? param.width : "40");
res.write("\" WRAP=\"");
res.write(param.wrap ? param.wrap : "VIRTUAL");
res.write("\">");
res.write(param.value != null ? param.value : "");
res.write("</TEXTAREA>");
}
}
/**
* renders an input type text
* input: - parameter object
*/
function renderInputText(param) {
if (param) {
res.write("<INPUT TYPE=\"TEXT\" NAME=\"" + param.name + "\"");
if (param.value)
res.write(" VALUE=\"" + param.value + "\"");
res.write(" SIZE=\"");
res.write(param.width ? param.width : "20");
res.write("\">");
}
}
/**
* renders an input type password
* input: - parameter object
*/
function renderInputPassword(param) {
if (param) {
res.write("<INPUT TYPE=\"PASSWORD\" NAME=\"" + param.name + "\"");
res.write(" SIZE=\"");
res.write(param.width ? param.width : "20");
res.write("\">");
}
}
/**
* function renders an input type file
*/
function renderInputFile(param) {
if (param) {
res.write("<INPUT TYPE=\"FILE\" NAME=\"" + param.name + "\"");
res.write(" SIZE=\"");
res.write(param.width ? param.width : "10");
res.write("\">");
}
}
/**
* renders an input type radio
* input: - parameter object
function renderInputRadio(param) {
if (param) {
res.write("<INPUT TYPE=\"RADIO\" NAME=\"" + param.value + "\"");
res.write(" VALUE=\"" + (this[param.value] ? this[param.value] : "") + "\"");
res.write(">");
}
}
*/
/**
* renders an input type checkbox
* input: - parameter object
*/
function renderInputCheckbox(param) {
if (param && param.name) {
res.write("<INPUT TYPE=\"CHECKBOX\" NAME=\"" + param.name + "\"");
res.write(" VALUE=\"1\"");
if (parseInt(param.value) == 1)
res.write(" CHECKED");
res.write(">");
}
}
/**
* renders a submit-button
* input: - parameter object
*/
function renderInputButton(param) {
if (param) {
res.write("<INPUT TYPE=\"SUBMIT\"");
res.write(" NAME=\"" + (param.name ? param.name : "submit") + "\"");
res.write(" VALUE=\"" + (param.value ? param.value : "submit") + "\"");
res.write(">");
}
}
/**
* open a normal href-tag
* valid attributes: - linkto | to (the url)
* - urlparam (get-parameter)
* - target
*/
function openLink(param) {
if (param.to || param.linkto) {
res.write("<A HREF=\"");
var url = param.to ? param.to : param.linkto;
// check if this is an external url
if (url.indexOf("://") > -1)
res.write(url);
else
res.write(this.href(url));
if (param.urlparam) res.write(param.urlparam);
res.write("\"");
if (param.target)
res.write(" TARGET=\"" + param.target + "\"");
res.write(">");
}
}
/**
* close a href-tag
*/
function closeLink() {
res.write("</A>");
}
/**
* renders a group of dropdowns for selecting
* date-value
*/
function renderDateDropdown(param) {
if (param.value) {
var ts = param.value;
} else {
var ts = new Date();
}
var prefix = param.name ? param.name : "date";
this.createDDparam(prefix,ts,"yyyy");
this.createDDparam(prefix,ts,"MM");
this.createDDparam(prefix,ts,"dd");
this.createDDparam(prefix,ts,"HH");
this.createDDparam(prefix,ts,"mm");
}
/**
* function renders a dropdown-element
* input values: parameter-object
* param.name = name of select-element
* param-object contains a HopObject for each option that is selectable
* each option contains the following properties:
* name = string to display in dropdown
* value = value of option
* selected = boolean (option matches the current selection)
*/
function chooser(param) {
res.write("<SELECT NAME=\"" + param.name + "\"");
res.write(">\n");
for (var i=0;i<param.size();i++) {
res.write("<OPTION VALUE=\"" + param.get(i).value + "\"");
if (param.get(i).selected)
res.write(" SELECTED");
res.write(">" + param.get(i).name + "</OPTION>\n");
}
res.write("</SELECT>\n");
}

14
code/Image/delete.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "delete")
this.__parent__.deleteImage(this);
else if (req.data.submit == "cancel")
res.redirect(this.weblog.images.href("main"));
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("delete");

4
code/Image/delete.skin Normal file
View file

@ -0,0 +1,4 @@
<FORM METHOD="POST">
<P>Warning! You are about to delete the image <B><% this.alias %></B>! Be aware of the fact that there is no "undo", so if you klick on delete here the image will be gone forever!</P>
<P><% this.input type="button" value="delete" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

14
code/Image/edit.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.weblog.images.href());
this.evalImg();
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("edit");

6
code/Image/edit.skin Normal file
View file

@ -0,0 +1,6 @@
<FORM METHOD="POST">
<P><% this.show %></P>
<P>Alias:<% this.alias as="editor" %></P>
<P>Alttext:<% this.alttext as="editor" %></P>
<P><% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %>
</FORM>

76
code/Image/macros.js Normal file
View file

@ -0,0 +1,76 @@
/**
* macro rendering alias of image
*/
function alias_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("alias",param));
else
res.write(this.alias);
renderSuffix(param);
}
/**
* macro rendering alternate text of image
*/
function alttext_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("alttext",param));
else
res.write(this.alttext);
renderSuffix(param);
}
/**
* macro renders a link for editing image
*/
function editlink_macro(param) {
renderPrefix(param);
var linkParam = new HopObject();
linkParam.linkto = "edit";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "edit");
else
this.renderImage(param);
this.closeLink();
renderSuffix(param);
}
/**
* macro rendering a link to delete
* if user is owner of this story
*/
function deletelink_macro(param) {
renderPrefix(param);
if (this.weblog && this.weblog.owner == user) {
var linkParam = new HopObject();
linkParam.linkto = "delete";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "delete");
else
this.renderImage(param);
this.closeLink();
}
renderSuffix(param);
}
/**
* macro renders a preview of this image
*/
function show_macro(param) {
renderPrefix(param);
res.write("<IMG SRC=\"" + getProperty("imgUrl") + this.weblog.alias + "/" + this.filename + "." + this.fileext + "\"");
res.write(" WIDTH=\"" + (param && param.as == "preview" ? Math.round(this.width / 2) : this.width) + "\"");
res.write(" HEIGHT=\"" + (param && param.as == "preview" ? Math.round(this.height / 2) : this.height) + "\"");
res.write(" BORDER=\"0\">");
renderSuffix(param);
}

8
code/Image/new.skin Normal file
View file

@ -0,0 +1,8 @@
<FORM METHOD="POST" ENCTYPE="multipart/form-data">
<P>Alias:<% this.alias as="editor" %></P>
<P>Alttext:<% this.alttext as="editor" %></P>
<P>Upload: <% this.input type="file" name="rawimage" %></P>
<P>maximum width: <% this.input type="text" name="maxWidth" width="5" %><BR>
maximum height: <% this.input type="text" name="maxHeight" width="5" %><BR></P>
<P><% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %>
</FORM>

View file

@ -0,0 +1,66 @@
/**
* save image as file on local disk
* but before check if image should be resized
* input params: - uploaded image
* - parameter-object
* return param: - parameter-object with add. props
*/
function saveImg(rawimage) {
if (rawimage && (!rawimage.contentType || rawimage.contentType.indexOf("image/") < 0)) {
// whatever the user has uploaded, it was no image!
this.cache.error = true;
res.message = "This was definetly no image!";
} else {
// determine filetype of image (one could do this also by checking the mimetype)
this.fileext = rawimage.name.substring(rawimage.name.lastIndexOf(".") + 1);
var img = new Image(rawimage.getContent());
// check if resizing is necessary
if (this.cache.maxWidth && this.cache.maxHeight && img.width > this.cache.maxWidth && img.height > this.cache.maxHeight) {
var hfact = this.cache.maxWidth / img.width;
var vfact = this.cache.maxHeight / img.height;
this.width = Math.round(img.width * (hfact < vfact ? hfact : vfact));
this.height = Math.round(img.height * (hfact < vfact ? hfact : vfact));
var doResize = true;
} else if (this.cache.maxWidth && img.width > this.cache.maxWidth) {
var fact = this.cache.maxWidth / img.width;
this.width = this.cache.maxWidth;
this.height = Math.round(img.height * fact);
var doResize = true;
} else if (this.cache.maxHeight && img.height > this.cache.maxHeight) {
var fact = this.cache.maxHeight / img.height;
this.height = this.cache.maxHeight;
this.width = Math.round(img.width * fact);
var doResize = true;
} else {
// no resizing done
this.width = img.width;
this.height = img.height;
}
if (doResize) {
img.resize(this.width,this.height);
if (rawimage.contentType == 'image/gif')
img.reduceColors(256);
}
// finally we save the image
img.saveAs(this.cache.saveTo + this.filename + "." + this.fileext);
}
return;
}
/**
* function checks if new image-parameters are correct ...
*/
function evalImg() {
if (req.data.alias) {
if (req.data.alias != this.alias) {
// alias has changed ...
this.weblog.images.changeAlias(this);
}
this.alttext = req.data.alttext;
res.message = "Changes saved successfully!";
res.redirect(this.weblog.images.href());
}
}

1
code/Image/preview.skin Normal file
View file

@ -0,0 +1 @@
<% this.show as="preview" %><% this.editlink prefix="&nbsp;" %><% this.deletelink prefix="&nbsp;" %><BR>

View file

@ -0,0 +1,10 @@
/**
* check if user is allowed to edit this story
*/
function checkPermissions() {
if (this.creator != user || user.isBlocked()) {
res.message = "Sorry, you're not allowed to edit this image!";
res.redirect(this.weblog.href());
}
}

View file

@ -0,0 +1,17 @@
_datasource=antville
_tablename=IMAGE
_id=ID
_parent=weblog.images[named]
weblog=WEBLOG_ID>weblog.ID
alias=ALIAS
filename=FILENAME
fileext=FILEEXT
width=WIDTH
height=HEIGHT
alttext=ALTTEXT
createtime=CREATETIME
creator=CREATOR>user.ID
modifytime=MODIFYTIME
modifier=MODIFIER>user.ID

14
code/ImageMgr/create.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.href());
newImg = this.evalNewImg();
res.skin = "main";
res.title = "Antville - " + this.__parent__.title;
res.head = this.__parent__.renderSkinAsString("style");
res.body = this.__parent__.renderSkinAsString("header");
res.body += newImg.renderSkinAsString("new");

21
code/ImageMgr/macros.js Normal file
View file

@ -0,0 +1,21 @@
/**
* macro renders imagepool as list
*/
function images_macro(param) {
renderPrefix(param);
for (var i=0;i<this.size();i++) {
this.get(i).renderSkin("preview");
}
renderSuffix(param);
}
/**
* macro renders editor for chosen image
*/
function imageeditor_macro(param) {
renderPrefix(param);
renderSuffix(param);
}

9
code/ImageMgr/main.hac Normal file
View file

@ -0,0 +1,9 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
res.skin = "main";
res.title = "Antville - " + this.__parent__.title;
res.head = this.__parent__.renderSkinAsString("style");
res.body = this.__parent__.renderSkinAsString("header");
res.body += this.renderSkinAsString("main");

2
code/ImageMgr/main.skin Normal file
View file

@ -0,0 +1,2 @@
<P><% this.images %></P>
<P><% this.link to="create" text="add new image" %></P>

View file

@ -0,0 +1,96 @@
/**
* function checks if image fits to the minimal needs
*/
function evalNewImg() {
var newImg = new image();
var rawimage = req.get("rawimage");
if (req.get("uploadError")) {
// looks like the file uploaded has exceeded uploadLimit ...
res.message = "File too big to handle!";
} else if (rawimage) {
if (rawimage.contentLength == 0) {
// looks like nothing was uploaded ...
res.message = "Please upload an image and fill out the form ...";
} else {
// first, check if alias already exists
if (!req.data.alias)
res.message = "You must enter an alias for this image!";
else if (this.get(req.data.alias))
res.message = "There is already an image with this alias!";
else {
newImg.filename = req.data.alias;
newImg.cache.saveTo = getProperty("imgPath") + this.__parent__.alias + "/";
// check if user wants to resize width
if (req.data.maxWidth)
newImg.cache.maxWidth = parseInt(req.data.maxWidth,10);
// check if user wants to resize height
if (req.data.maxHeight)
newImg.cache.maxHeight = parseInt(req.data.maxHeight,10);
// save/resize the image
newImg.saveImg(rawimage);
// any errors?
if (!newImg.cache.error) {
// the image is on disk, so we add the image-object
this.addImg(newImg);
res.redirect(this.href());
}
}
}
}
return (newImg);
}
/**
* function adds an image to pool
*/
function addImg(newImg) {
newImg.alias = req.data.alias;
newImg.alttext = req.data.alttext;
newImg.creator = user;
newImg.createtime = new Date();
if (this.add(newImg))
res.message = "The image " + newImg.alias + " was added successfully!";
else
res.message = "Ooops! Adding the image " + newImg.alias + " failed!";
return;
}
/**
* alias of image has changed, so we remove it and add it again with it's new alias
*/
function changeAlias(currImg) {
// var oldAlias = currImg.alias;
currImg.setParent(this);
this.remove(currImg);
this.set(currImg.alias,null);
currImg.alias = req.data.alias;
this.add(currImg);
return;
}
/**
* delete an image
*/
function deleteImage(currImg) {
currImg.setParent(this);
// first we try to remove the image from disk
var f = new File(getProperty("imgPath") + currImg.weblog.alias, currImg.filename + "." + currImg.fileext);
if (f.remove()) {
if (this.remove(currImg))
res.message = "The image was deleted successfully!";
else
res.message = "Ooops! Couldn't delete the image!";
} else
res.message = "Ooops! Couldn't remove the image from disk!";
res.redirect(this.href("main"));
}

View file

@ -0,0 +1,14 @@
/**
* function checks if user is allowed to add/edit images of this weblog
*/
function checkPermissions() {
if (!user.uid) {
res.message = "Please login before!";
user.cache.referer = this.href();
res.redirect(this.__parent__.members.href("login"));
} else if (this.__parent__.owner != user) {
res.message = "Sorry, you're not allowed to edit images";
res.redirect(this.href());
}
}

View file

@ -0,0 +1,5 @@
_subnodes=<image.WEBLOG_ID
_properties=image.ALIAS
_properties.aresubnodes=true
_subnodes.order=CREATETIME desc
_subnodes.loadmode=aggressive

14
code/MemberMgr/edit.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user has right to edit this comment
this.checkPermissions();
res.skin = "main";
if (req.data.submit == "cancel")
res.redirect(this.__parent__.href());
else if (req.data.submit == "save")
this.updateUser();
res.head = this.__parent__.renderSkinAsString("style");
res.body = this.__parent__.renderSkinAsString("header");
res.body += user.renderSkinAsString("edit");

34
code/MemberMgr/login.hac Normal file
View file

@ -0,0 +1,34 @@
res.skin = "main";
if (req.data.name && req.data.password) {
// check if login is successful
if (user.login(req.data.name, req.data.password)) {
// login successful
user.lastVisit = new Date();
res.message = "Welcome to Antville, " + user.name + "! Have fun!";
if (!user.cache.referer) {
if (user.weblog) {
user.weblog.setParent(root);
res.redirect(user.weblog.href());
} else
res.redirect(root.href());
} else {
var redirectTo = user.cache.referer;
user.cache.referer = null;
res.redirect(redirectTo);
}
} else
res.message = "Login failed! Maybe a typo?";
} else {
if (!res.message)
res.message = "Please enter your login name and password:";
}
if (!user.cache.referer && req.data.http_referer)
user.cache.referer = req.data.http_referer;
res.title = "Anville Member Login";
res.head = this.__parent__.renderSkinAsString("style");
res.body = this.__parent__.renderSkinAsString("header");
res.body += this.renderSkinAsString("login");

View file

@ -0,0 +1,6 @@
<FORM METHOD="POST">
<P><% this.input type="text" name="name" prefix="Username:&nbsp;" %><BR>
<% this.input type="password" name="password" prefix="Password:&nbsp;" %><BR>
<% this.input type="button" name="login" value="login!" %></P>
<P>If you're not registered, you can do this <% this.link to="register" text="here" %></P>
</FORM>

11
code/MemberMgr/logout.hac Normal file
View file

@ -0,0 +1,11 @@
if (req.data.http_referer)
var redirectTo = req.data.http_referer;
else if (user.weblog)
var redirectTo = user.weblog.href();
else
var redirectTo = root.href();
res.message = "Good bye, " + user.name + "! Lookin' forward to see you again!";
user.logout();
user.cache.referer = null;
res.redirect(redirectTo);

View file

@ -0,0 +1,84 @@
/**
* check if a registration attempt is ok
*/
function evalRegistration() {
var reg = this.checkReg();
if (!reg.error) {
var newUser = user.register(reg.name, reg.password1);
if (newUser) {
newUser.name = reg.name;
newUser.email = reg.email;
newUser.url = reg.url;
newUser.description = reg.description;
user.login(reg.name, reg.password1);
user.sendConfirmationMail();
res.message = "Welcome " + user.name + ". Have fun!<br>";
res.redirect(root.href());
} else
res.message = "Sorry, we already have a member with that name.";
}
return (reg);
}
/**
* check if all values necessary to register
* are given and return them as properties of a
* temporary HopObject
*/
function checkReg() {
var reg = new HopObject();
if (!res.message) res.message = "Please fill out the form completely and then click the button to register.";
if (req.data.name)
reg.name = req.data.name;
else
reg.error = true;
if (req.data.password1 && req.data.password2) {
if (req.data.password1 == req.data.password2) {
reg.password1 = req.data.password1;
reg.password2 = req.data.password2;
} else {
res.message = "Passwords didn't match! Please re-enter:";
reg.error = true;
}
} else
reg.error = true;
if (req.data.email) {
reg.email = req.data.email;
if (!checkEmail(req.data.email)) {
res.message = "Ooops! The email-address you entered is not valid!";
reg.error = true;
}
} else
reg.error = true;
if (req.data.description)
reg.description = req.data.description;
if (req.data.url)
reg.url = req.data.url;
return (reg);
}
/**
* update user-profile
*/
function updateUser() {
if (req.data.oldpwd && req.data.newpwd1 && req.data.newpwd2) {
if (user.password != req.data.oldpwd) {
res.message = "Old password incorrect!";
res.redirect(this.href("edit"));
} else if (req.data.newpwd1 != req.data.newpwd2) {
res.message = "Ooops! Passwords didn't match! Please type in again!";
res.redirect(this.href("edit"));
} else
user.password = req.data.newpwd1;
}
user.url = req.data.url;
user.email = req.data.email;
user.description = req.data.description;
res.message = "Changes were saved successfully!";
res.redirect(this.__parent__.href());
}

View file

@ -0,0 +1,12 @@
res.skin = "main";
if (req.data.submit == "cancel")
res.redirect(root.href());
else
var reg = this.evalRegistration();
res.title = "Antville member registration";
res.head = root.renderSkinAsString("style");
res.body = root.renderSkinAsString("header");
res.body += this.renderSkinAsString("register",reg);

View file

@ -0,0 +1,11 @@
<FORM METHOD="POST">
<P>Username:&nbsp;<% this.input type="text" name="name" %></P>
Your Password:&nbsp;<% this.input type="password" name="password1" %><BR>
type again:&nbsp;<% this.input type="password" name="password2" %><BR>
Email:&nbsp;<% this.input type="text" name="email" %><BR>
URL:&nbsp;<% this.input type="text" name="url" %><BR>
Description:&nbsp;<% this.input type="textarea" name="description" %><BR>
<% this.input type="button" value="register" %>&nbsp;<% this.input type="button" value="cancel" %>
</FORM>

View file

@ -0,0 +1,11 @@
/**
* function checks if user is allowed to edit her/his profile
*/
function checkPermissions() {
if (!user.uid) {
res.message = "Please login before editing your profile!";
user.cache.referer = this.href("edit");
res.redirect(this.href("login"));
}
}

View file

@ -0,0 +1 @@
<FONT SIZE="-1">Logged in as <% currentUser.name %> ... <% this.link to="edit" text="edit your profile" %> or <% this.link to="logout" text="logout" %></FONT>

View file

@ -0,0 +1 @@
<FONT SIZE="-1">You're not logged in ... <% this.link to="login" text="login" %></FONT>

2
code/Root/header.skin Normal file
View file

@ -0,0 +1,2 @@
<P><FONT SIZE="+3"><B>Antville</B>&nbsp;</FONT><% response.message %></P>
<% root.loginstatus %>

37
code/Root/macros.js Normal file
View file

@ -0,0 +1,37 @@
/**
* macro rendering loginStatus of user
* valid params: - loginSkin
* - logoutSkin
*/
function loginstatus_macro(param) {
if (user.uid)
this.members.renderSkin("statusloggedin");
else if (getActionName() != "login")
this.members.renderSkin("statusloggedout");
}
/**
* macro renders the 10 freshest weblogs
*/
function webloglist_macro(param) {
if (this.size()) {
renderPrefix(param);
for (var i=0;i<(this.size() > 10 ? 10 : this.size());i++) {
if (this.get(i).isOnline() && this.get(i).lastupdate)
this.get(i).renderSkin("preview");
}
renderSuffix(param);
}
}
/**
* macro renders the number of weblogs
*/
function weblogcounter_macro(param) {
renderPrefix(param);
res.write(this.size());
renderSuffix(param);
}

6
code/Root/main.hac Normal file
View file

@ -0,0 +1,6 @@
res.skin = "main";
res.head = this.renderSkinAsString("style");
res.title = "Antville";
res.body = this.renderSkinAsString("header");
res.body += this.renderSkinAsString("main");

7
code/Root/main.skin Normal file
View file

@ -0,0 +1,7 @@
<P>This is Antville, a small but fancy Weblog-Application build with <% this.link to="http://helma.org" text="Helma Object Publisher" %></P>
<P>If you don't own a Weblog yourself, you can <% this.link to="new" text="create one" %></P>
<P><B>Status:</B></P>
<% this.weblogcounter %> WebLogs created<BR>
<% this.webloglist prefix="<BR>last updated weblogs:" %><P>

22
code/Root/new.hac Normal file
View file

@ -0,0 +1,22 @@
res.skin = "main";
res.title = "Antville - creating a new Weblog";
res.head = this.renderSkinAsString("style");
if (!user.uid) {
res.message = "Please login first";
user.cache.referer = this.href("new");
res.redirect(root.members.href("login"));
} else {
if (req.data.submit == "cancel")
res.redirect(root.href());
else if (user.isBlocked())
res.redirect(root.href());
else if (user.getWeblog()) {
res.message = "You already own a Weblog! You'll need a new account to create another one.";
res.redirect(root.members.href("register"));
} else
var newLog = this.evalNewWeblog();
res.body = this.renderSkinAsString("header");
res.body += this.renderSkinAsString("new",newLog);
}

7
code/Root/new.skin Normal file
View file

@ -0,0 +1,7 @@
<FORM METHOD="POST">
<P>Title:&nbsp;<% this.input type="text" name="title" %><BR>
Alias:&nbsp;<% this.input type="text" name="alias" %><BR>
<% this.input type="button" value="create" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

View file

@ -0,0 +1,79 @@
/**
* evaluating new weblog
*/
function evalNewWeblog() {
var newLog = new weblog();
if (req.data.title && req.data.alias) {
newLog.title = req.data.title;
newLog.alias = req.data.alias;
if (this.checkIfExists(newLog.alias)) {
res.message = "Sorry, we already have a weblog with this alias!";
newLog.error = true;
} else {
// now we can safely create a new weblog
this.createNewWeblog(newLog);
}
} else {
newLog.error = true;
newLog.title = newLog.alias = "";
if (!res.message) res.message = "Please fill in the form to create your new Weblog!";
}
return (newLog);
}
/**
* check if alias is already in use
*/
function checkIfExists(alias) {
if (this.get(alias))
return true;
return false;
}
/**
* create a new weblog
*/
function createNewWeblog(newLog) {
newLog.owner = user;
newLog.creator = user;
newLog.createtime = new Date();
newLog.online = 0;
newLog.discussions = 1;
newLog.archive = 1;
newLog.blocked = 0;
newLog.birthdate = new Date();
newLog.textfont = "Arial, Helvetica, sans-serif";
newLog.textsize = "10pt";
newLog.textcolor = "000000";
newLog.linkcolor = "0000FF";
newLog.alinkcolor = "FF0000";
newLog.vlinkcolor = "0000CC";
newLog.titlefont = "Arial, Helvetica, sans-serif";
newLog.titlesize = "12pt";
newLog.titlecolor = "CC0000";
newLog.days = 3;
newLog.createImgDirectory()
this.add(newLog);
user.weblog = newLog;
res.message = "Your weblog was created successfully! Have fun!";
res.redirect(newLog.href());
}
/**
* alias of image has changed, so we remove it and add it again with it's new alias
*/
function changeAlias(currImg) {
// var oldAlias = currImg.alias;
currImg.setParent(this);
this.remove(currImg);
this.set(currImg.alias,null);
currImg.alias = req.data.alias;
this.add(currImg);
return;
}

39
code/Root/style.skin Normal file
View file

@ -0,0 +1,39 @@
<STYLE TYPE="text/css">
<!--
body { font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
font-weight: normal;
color: #000000;
}
.calendar { border: 1px solid black;
}
.calendarHeader { font-size: 8pt;
font-weight: bold;
color: #FFFFFF;
background-color: #666666;
}
.calendarDay { font-size: 8pt;
font-weight: normal;
border: 1px solid #666666;
text-align: center;
}
.calendarSelectedDay { font-size: 8pt;
font-weight: normal;
border: 1px solid #666666;
background-color: #FFFFFF;
text-align: center;
}
.calendarFooter { font-size: 8pt;
font-weight: bold;
color: #FFFFFF;
background-color: #999999;
}
// -->
</STYLE>

View file

@ -0,0 +1,8 @@
_subnodes=weblog.ID
_properties=weblog.ALIAS
_properties.aresubnodes=true
_subnodes.order=LASTUPDATE desc
_subnodes.loadmode=aggressive
members=[mountpoint]membership

View file

@ -0,0 +1,9 @@
<TABLE BGCOLOR="#FF9900" BORDER="0" CELLSPACING="0" CELLPADDING="2">
<TR>
<TD NOWRAP><% this.link to="main" text="&bull;&nbsp;home" %></TD>
<TD NOWRAP><% this.link to="edit" text="&bull;&nbsp;preferences" %></TD>
<TD NOWRAP><% this.link to="create" text="&bull;&nbsp;create story" %></TD>
<TD NOWRAP><% this.link to="images" text="&bull;&nbsp;image editor" %></TD>
<TD NOWRAP><% this.link to="skins" text="&bull;&nbsp;skin editor" %></TD>
</TR>
</TABLE>

20
code/Site/calendar.skin Normal file
View file

@ -0,0 +1,20 @@
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="2" BGCOLOR="#CCCCCC" CLASS="calendar">
<TR>
<TD COLSPAN="7" ALIGN="CENTER" CLASS="calendarHeader" NOWRAP><% param.month %>&nbsp;<% param.year %></TD>
</TR>
<TR>
<TD CLASS="calendarDay" NOWRAP>Mo</TD>
<TD CLASS="calendarDay" NOWRAP>Tu</TD>
<TD CLASS="calendarDay" NOWRAP>We</TD>
<TD CLASS="calendarDay" NOWRAP>Th</TD>
<TD CLASS="calendarDay" NOWRAP>Fr</TD>
<TD CLASS="calendarDay" NOWRAP>Sa</TD>
<TD CLASS="calendarDay" NOWRAP>Su</TD>
</TR>
<% param.calendar %>
<TR>
<TD COLSPAN="3" ALIGN="RIGHT" CLASS="calendarFooter" NOWRAP><% param.back %></TD>
<TD CLASS="calendarFooter" NOWRAP>&nbsp;</TD>
<TD COLSPAN="3" CLASS="calendarFooter" NOWRAP><% param.forward %></TD>
</TR>
</TABLE>

View file

@ -0,0 +1 @@
<TD CLASS="calendarDay" NOWRAP><% param.day %></TD>

View file

@ -0,0 +1 @@
<TD CLASS="calendarSelectedDay" NOWRAP><% param.day %></TD>

View file

@ -0,0 +1,3 @@
<TR>
<% param.week %>
</TR>

14
code/Site/create.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is allowed to edit this story
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.href());
res.skin = "main";
res.title = "Antville - " + this.title;
res.head = this.renderSkinAsString("style");
newStory = this.evalNewStory();
res.body = this.renderSkinAsString("header");
res.body += newStory.renderSkinAsString("edit");

14
code/Site/edit.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.href());
else if (req.data.submit == "save")
this.updateWeblog();
res.skin = "main";
res.title = "Antville - " + this.title;
res.head = this.renderSkinAsString("style");
res.body = this.renderSkinAsString("header");
res.body += this.renderSkinAsString("edit");

20
code/Site/edit.skin Normal file
View file

@ -0,0 +1,20 @@
<P><FORM METHOD="POST">
Title:&nbsp;<% this.title as="editor" width="40" %><BR>
Tagline:&nbsp;<% this.tagline as="editor" width="40" %><BR>
Birthdate:&nbsp;<% this.birthdate as="editor" %><BR>
Background color:&nbsp;<% this.bgcolor as="editor" width="10" %><BR>
Textfont:&nbsp;<% this.textfont as="editor" width="40" %><BR>
Textsize:&nbsp;<% this.textsize as="editor" width="10" %><BR>
Textcolor:&nbsp;<% this.textcolor as="editor" width="10" %><BR>
Linkcolor:&nbsp;<% this.linkcolor as="editor" width="10" %><BR>
ALinkcolor:&nbsp;<% this.alinkcolor as="editor" width="10" %><BR>
VLinkcolor:&nbsp;<% this.vlinkcolor as="editor" width="10" %><BR>
Titlefont:&nbsp;<% this.titlefont as="editor" width="40" %><BR>
Titlesize:&nbsp;<% this.titlesize as="editor" width="10" %><BR>
Titlecolor:&nbsp;<% this.titlecolor as="editor" width="10" %><BR>
show days:&nbsp;<% this.showdays as="editor" width="5"%><BR>
online:&nbsp;<% this.online as="editor" %><BR>
hasDiscussions:&nbsp;<% this.hasdiscussions as="editor" %><BR>
enable archive:&nbsp;<% this.showarchive as="editor" %><BR>
<% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %>
</FORM></P>

6
code/Site/header.skin Normal file
View file

@ -0,0 +1,6 @@
<P><FONT SIZE="+3"><B><% this.title %></B></FONT>&nbsp;<FONT SIZE="-1" COLOR="#FF0000"><% response.message %></FONT>
<% this.age prefix="<BR>online since:&nbsp;" show="days" suffix=" Days" %>
<% this.lastupdate prefix="<BR>last updated:&nbsp;" format="EEEE, dd.MM.yyyy, HH:mm" suffix="&nbsp;Uhr" %></P>
<% this.loginstatus %>
<% this.navigation %>

411
code/Site/macros.js Normal file
View file

@ -0,0 +1,411 @@
/**
* macro rendering title of weblog
*/
function title_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("title",param));
else {
if (param && param.linkto) {
this.openLink(param);
res.write(this.title);
this.closeLink(param);
} else
res.write(this.title);
}
renderSuffix(param);
}
/**
* macro rendering alias of weblog
*/
function alias_macro(param) {
renderPrefix(param);
res.write(this.alias);
renderSuffix(param);
}
/**
* macro rendering tagline of weblog
*/
function tagline_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("tagline",param));
else
res.write(this.tagline);
renderSuffix(param);
}
/**
* macro rendering birthdate of weblog
*/
function birthdate_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderDateDropdown(this.createInputParam("birthdate",param));
else
res.write(this.birthdate.format());
renderSuffix(param);
}
/**
* macro rendering bgcolor of weblog
*/
function bgcolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("bgcolor",param));
else
res.write(this.bgcolor);
renderSuffix(param);
}
/**
* macro rendering textfont of weblog
*/
function textfont_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("textfont",param));
else
res.write(this.textfont);
renderSuffix(param);
}
/**
* macro rendering textsize of weblog
*/
function textsize_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("textsize",param));
else
res.write(this.textsize);
renderSuffix(param);
}
/**
* macro rendering textcolor of weblog
*/
function textcolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("textcolor",param));
else
res.write(this.textcolor);
renderSuffix(param);
}
/**
* macro rendering linkcolor of weblog
*/
function linkcolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("linkcolor",param));
else
res.write(this.linkcolor);
renderSuffix(param);
}
/**
* macro rendering alinkcolor of weblog
*/
function alinkcolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("alinkcolor",param));
else
res.write(this.alinkcolor);
renderSuffix(param);
}
/**
* macro rendering vlinkcolor of weblog
*/
function vlinkcolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("vlinkcolor",param));
else
res.write(this.vlinkcolor);
renderSuffix(param);
}
/**
* macro rendering titlefont of weblog
*/
function titlefont_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("titlefont",param));
else
res.write(this.titlefont);
renderSuffix(param);
}
/**
* macro rendering titlesize of weblog
*/
function titlesize_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("titlesize",param));
else
res.write(this.titlesize);
renderSuffix(param);
}
/**
* macro rendering titlecolor of weblog
*/
function titlecolor_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("titlecolor",param));
else
res.write(this.titlecolor);
renderSuffix(param);
}
/**
* macro rendering lastupdate of weblog
*/
function lastupdate_macro(param) {
if (this.lastUpdate) {
renderPrefix(param);
if (param.format)
res.write(this.lastupdate.format(param.format));
else
res.write(this.lastupdate.format("yyyy.MM.dd HH:mm"));
renderSuffix(param);
}
}
/**
* macro rendering online-status of weblog
*/
function online_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputCheckbox(this.createInputParam("online",param));
else
res.write(this.online ? "yes" : "no");
renderSuffix(param);
}
/**
* macro rendering discussion-flag of weblog
*/
function hasdiscussions_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputCheckbox(this.createInputParam("discussions",param));
else
res.write(parseInt(this.discussions,10) ? "yes" : "no");
renderSuffix(param);
}
/**
* macro rendering nr. of days to show on weblog-fontpage
*/
function showdays_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("days",param));
else
res.write(this.days);
renderSuffix(param);
}
/**
* macro rendering archive-flag of weblog
*/
function showarchive_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputCheckbox(this.createInputParam("archive",param));
else
res.write(parseInt(this.archive,10) ? "yes" : "no");
renderSuffix(param);
}
/**
* macro rendering loginStatus of user
* valid params: - loginSkin
* - logoutSkin
*/
function loginstatus_macro(param) {
if (user.uid)
this.members.renderSkin("statusloggedin");
else if (getActionName() != "login")
this.members.renderSkin("statusloggedout");
}
/**
* macro rendering two different navigation-skins
* depending on user-status & rights
*/
function navigation_macro(param) {
renderPrefix(param);
if (this.owner == user) {
// hey, this is the admin, so give him the admin-navigation
this.renderSkin("adminnavigation");
} else {
// normal user, so we take the normal navigation
this.renderSkin("usernavigation");
}
renderSuffix(param);
}
/**
* macro rendering storylist
* but check if story is online ...
* if not, we only display it when owner is viewing
*/
function storylist_macro() {
if (this.size() > 0) {
var idx = 0;
var days = parseInt(this.days) ? parseInt(this.days) : 2;
if (req.data.show) {
var currGroup = this.get(req.data.show);
if (currGroup) {
idx = this.contains(currGroup);
days = 1;
}
}
for (var i=idx;i<idx + days;i++) {
var currDay = this.get(i);
if (currDay) {
for (var j=0;j<currDay.size();j++) {
var currStory = currDay.get(j);
currStory.setParent(currDay);
if (currStory.isOnline() || currStory.author == user)
currStory.renderSkin("preview");
}
}
}
} else
this.renderSkin("welcome");
}
/**
* macro renders a calendar
*/
function calendar_macro() {
// define variables needed in this function
var now = new Date();
var calParam = new HopObject();
calParam.calendar = "";
var dayParam = new HopObject();
var weekParam = new HopObject();
// create new calendar-object
var cal = new java.util.GregorianCalendar();
cal.set(java.util.Calendar.DATE,1);
if (req.data.show) {
var reqYear = parseInt(req.data.show.substring(0,4),10);
var reqMonth = parseInt(req.data.show.substring(4,6),10) - 1;
if (reqYear && reqMonth) {
cal.set(java.util.Calendar.YEAR,reqYear);
cal.set(java.util.Calendar.MONTH,reqMonth);
}
}
var lastDay = cal.getActualMaximum(java.util.Calendar.DATE);
var startAt = cal.get(java.util.Calendar.DAY_OF_WEEK) - cal.getFirstDayOfWeek();
var currMonth = cal.get(java.util.Calendar.MONTH);
calParam.month = cal.getTime().format("MMMM");
calParam.year = cal.getTime().format("yyyy");
calParam.back = this.renderLinkToPrev(cal.clone());
for (var i=0;i<Math.ceil((startAt + lastDay) / 7);i++) {
weekParam.week = "";
for (var j=0;j<7;j++) {
if(i==0 && j<startAt) {
dayParam.day = "&nbsp;";
} else {
if (cal.get(java.util.Calendar.MONTH) != currMonth) {
dayParam.day = "&nbsp;";
} else {
var currGroupname = cal.getTime().format("yyyyMMdd");
dayParam.day = this.renderCalendarDay(currGroupname,cal.get(java.util.Calendar.DATE));
}
// check which skin we should render
if (req.data.show && cal.getTime().format("yyyyMMdd") == req.data.show)
dayParam.useskin = "calendarselday";
else
dayParam.useskin = "calendarday";
// render the link to next month (if it makes sense)
if (cal.get(java.util.Calendar.DATE) == lastDay)
calParam.forward = this.renderLinkToNext(cal.clone());
cal.add(java.util.Calendar.DATE,1);
}
weekParam.week += this.renderSkinAsString((dayParam.useskin ? dayParam.useskin : "calendarday"),dayParam);
}
calParam.calendar += this.renderSkinAsString("calendarweek",weekParam);
}
this.renderSkin("calendar",calParam);
}
/**
* macro renders age of weblog
*/
function age_macro(param) {
if (this.birthdate) {
renderPrefix(param);
if (param && param.format)
res.write(this.birthdate.format(param.format));
else if (param && param.show == "days")
res.write(Math.floor((new Date() - this.birthdate) / 86400000));
else
res.write(this.birthdate);
renderSuffix(param);
}
}
/**
* macro renders an image out of image-pool
* either as plain image or as image-link
* overrideable parameters: width,height,alttext,border
* additional parameters: align, valign
*/
function image_macro(param) {
if (param && param.name) {
renderPrefix(param);
this.renderImage(param);
renderSuffix(param);
}
}

6
code/Site/main.hac Normal file
View file

@ -0,0 +1,6 @@
res.skin = "main";
res.title = "Antville - " + this.title;
res.head = this.renderSkinAsString("style");
res.body = this.renderSkinAsString("main");

5
code/Site/main.skin Normal file
View file

@ -0,0 +1,5 @@
<% this.skin name="header" %>
<% this.calendar %>
<% this.storylist %>

View file

@ -0,0 +1,158 @@
/**
* function checks if story fits to the minimal needs (must have at least a text ;-)
*/
function evalNewStory() {
var newStory = new story();
if (req.data.text) {
newStory.weblog = this;
newStory.title = req.data.title;
newStory.text = req.data.text;
newStory.online = parseInt(req.data.online) ? parseInt(req.data.online) : 0;
newStory.author = user;
newStory.createtime = new Date();
newStory.day = newStory.createtime.format("yyyyMMdd");
this.add(newStory);
this.lastupdate = newStory.createtime;
res.message = "The story was created successfully!";
res.redirect(this.href());
} else
return (newStory);
}
/**
* check if there are any stories in the previous month
*/
function renderLinkToPrev(cal) {
if (!this.size())
return ("&nbsp;");
if (parseInt(this.get(this.size()-1).groupname,10) < parseInt(cal.getTime().format("yyyyMMdd"),10)) {
// there are any stories left back in history, so try to get them ...
prevDay = false;
while (!prevDay) {
cal.add(java.util.Calendar.DATE,-1);
if (this.get(cal.getTime().format("yyyyMMdd")))
prevDay = this.get(cal.getTime().format("yyyyMMdd"));
}
return ("<A HREF=\"" + this.href("main") + "?show="+ prevDay.groupname + "\">" + cal.getTime().format("MMMM") + "</A>");
} else {
return ("&nbsp;");
}
}
/**
* check if there are any stories in the previous month
*/
function renderLinkToNext(cal) {
if (!this.size())
return ("&nbsp;");
if (parseInt(this.get(0).groupname,10) > parseInt(cal.getTime().format("yyyyMMdd"),10)) {
// there are any stories, so try to get them ...
nextDay = false;
while (!nextDay) {
cal.add(java.util.Calendar.DATE,1);
if (this.get(cal.getTime().format("yyyyMMdd")))
nextDay = this.get(cal.getTime().format("yyyyMMdd"));
}
return ("<A HREF=\"" + this.href("main") + "?show="+ nextDay.groupname + "\">" + cal.getTime().format("MMMM") + "</A>");
} else {
return ("&nbsp;");
}
}
/**
* delete a story
*/
function deleteStory(currStory) {
currStory.setParent(this);
if (this.remove(currStory))
res.message = "The story was deleted successfully!";
else
res.message = "Ooops! Couldn't delete the story!";
res.redirect(this.href("main"));
}
/**
* function saves new properties of weblog
*/
function updateWeblog() {
this.title = req.data.title;
this.tagline = req.data.tagline;
this.bgcolor = req.data.bgcolor;
this.textfont = req.data.textfont;
this.textsize = req.data.textsize;
this.textcolor = req.data.textcolor;
this.linkcolor = req.data.linkcolor;
this.alinkcolor = req.data.alinkcolor;
this.vlinkcolor = req.data.vlinkcolor;
this.titlefont = req.data.titlefont;
this.titlesize = req.data.titlesize;
this.titlecolor = req.data.titlecolor;
this.days = parseInt(req.data.days,10);
this.online = parseInt(req.data.online,10);
this.discussions = parseInt(req.data.discussions,10);
this.archive = parseInt(req.data.archive,10);
this.birthdate = this.checkdate("birthdate");
res.message = "The changes were saved successfully!";
res.redirect(this.href());
}
/**
* function takes postdate of story, checks it and
* returns Date-object
*/
function checkdate(prefix) {
if (req.data[prefix + "Year"] && req.data[prefix + "Month"] && req.data[prefix + "Date"] && req.data[prefix + "Hours"] && req.data[prefix + "Minutes"]) {
var pd = new Date();
pd.setYear(parseInt(req.data[prefix + "Year"],10));
pd.setMonth(parseInt(req.data[prefix + "Month"],10));
pd.setDate(parseInt(req.data[prefix + "Date"],10));
pd.setHours(parseInt(req.data[prefix + "Hours"],10));
pd.setMinutes(parseInt(req.data[prefix + "Minutes"],10));
return (pd);
} else
return (new Date());
}
/**
* function returns true if discussions are enabled
* for this weblog
*/
function hasDiscussions() {
if (parseInt(this.discussions,10))
return true;
res.message = "Sorry, posting comments is not enabled here!";
return false;
}
/**
* function returns true if weblog is online
* otherwise false
*/
function isOnline() {
if (parseInt(this.online,10))
return true;
return false;
}
/**
* function creates the directory that will contain the images of this weblog
*/
function createImgDirectory() {
var dir = new File(getProperty("imgPath") + this.alias + "/");
return (dir.mkdir());
}

1
code/Site/preview.skin Normal file
View file

@ -0,0 +1 @@
&bull;<% this.title linkto="main" %> (last updated: <% this.lastupdate format="EEEE, dd.MM.yyyy HH:mm" %>)<BR>

View file

@ -0,0 +1,55 @@
/**
* function checks if a link to the given group makes sense
*/
function renderCalendarDay(currGroupname,text) {
var now = new Date();
var currGroup = this.get(currGroupname);
if (currGroup && currGroup.size()) {
if (user == this.owner)
var linkit = true;
else {
var linkit = false;
if (currGroupname <= now.format("yyyyMMdd")) {
for (var i=0;i<currGroup.size();i++) {
if (currGroup.get(i).isOnline())
linkit = true;
}
}
}
if (linkit) {
var text = "<A HREF=\"" + this.href("main") + "?show=" + currGroupname + "\">" + text + "</A>";
/*
if (!req.data.show && currGroupname == now.format("yyyyMMdd"))
text = "<B>" + text + "</B>";
else if (req.data.show && req.data.show == currGroupname)
text = "<B>" + text + "</B>";
*/
}
}
return (text);
}
/**
* function renders an image
*/
function renderImage(param) {
if (param.linkto)
this.openLink(param);
var img = this.images.get(param.name);
if (img) {
res.write("<IMG SRC=\"" + getProperty("imgUrl") + this.alias + "/" + img.filename + "." + img.fileext + "\"");
res.write(" WIDTH=\"" + (param.width ? param.width : img.width) + "\"");
res.write(" HEIGHT=\"" + (param.height ? param.height : img.height) + "\"");
res.write(" ALT=\"" + (param.alttext ? param.alttext : img.alttext) + "\"");
if (param.align)
res.write(" ALIGN=\"" + param.align + "\"");
if (param.valign)
res.write(" VALIGN=\"" + param.valign + "\"");
res.write(" BORDER=\"" + (param.border ? param.border : 0) + "\">");
}
if (param.linkto)
this.closeLink(param);
}

View file

@ -0,0 +1,14 @@
/**
* function checks if user is allowed to add a story to this weblog
*/
function checkPermissions() {
if (!user.uid) {
res.message = "Please login before editing a new story!";
user.cache.referer = this.href("create");
res.redirect(this.members.href("login"));
} else if (this.owner != user) {
res.message = "Sorry, you're not allowed to add a story!";
res.redirect(this.href());
}
}

45
code/Site/style.skin Normal file
View file

@ -0,0 +1,45 @@
<STYLE TYPE="text/css">
<!--
body { font-family: <% this.textfont %>;
font-size: <% this.textsize %>;
font-weight: normal;
color: #<% this.textcolor %>;
}
.title { font-family: <% this.titlefont %>;
font-size: <% this.titlesize %>;
color: <% this.titlecolor %>;
font-weight: bold;
}
.calendar { border: 1px solid black;
}
.calendarHeader { font-size: 8pt;
font-weight: bold;
color: #FFFFFF;
background-color: #666666;
}
.calendarDay { font-size: 8pt;
font-weight: normal;
border: 1px solid #666666;
text-align: center;
}
.calendarSelectedDay { font-size: 8pt;
font-weight: normal;
border: 1px solid #666666;
background-color: #FFFFFF;
text-align: center;
}
.calendarFooter { font-size: 8pt;
font-weight: bold;
color: #FFFFFF;
background-color: #999999;
}
// -->
</STYLE>

45
code/Site/type.properties Normal file
View file

@ -0,0 +1,45 @@
_datasource=antville
_tablename=WEBLOG
_subnodes=<story.WEBLOG_ID
_subnodes.groupby=DAY
_subnodes.order=CREATETIME DESC
_subnodes.groupby.order=CREATETIME DESC
_id=ID
owner=OWNER_ID>user.ID
title=TITLE
alias=ALIAS
tagline=TAGLINE
birthdate=BIRTHDATE
bgcolor=BGCOLOR
textfont=TEXTFONT
textcolor=TEXTCOLOR
textsize=TEXTSIZE
linkcolor=LINKCOLOR
alinkcolor=ALINKCOLOR
vlinkcolor=VLINKCOLOR
titlefont=TITLEFONT
titlecolor=TITLECOLOR
titlesize=TITLESIZE
online=ISONLINE
lastupdate=LASTUPDATE
blocked=ISBLOCKED
discussions=HASDISCUSSIONS
days=SHOWDAYS
archive=SHOWARCHIVE
createtime=CREATETIME
creator=CREATOR>user.ID
modifytime=MODIFYTIME
modifier=MODIFIER>user.ID
skinmanager=[virtual]skin.NAME
skinmanager.subnodeRelation=<skin.WEBLOG_ID
skinmanager.areSubnodes=true
skinmanager.groupby=PROTO
members=[mountpoint]membership
images=[mountpoint]imagemgr
skins=[mountpoint]skinmgr

View file

@ -0,0 +1,5 @@
<TABLE BGCOLOR="#FF9900" BORDER="0" CELLSPACING="0" CELLPADDING="2">
<TR>
<TD NOWRAP><% this.link to="main" text="&bull;&nbsp;home" %></TD>
</TR>
</TABLE>

1
code/Site/welcome.skin Normal file
View file

@ -0,0 +1 @@
<P>This is a completely empty weblog, but who nows? Maybe sometimes ...</P>

6
code/Skin/edit.skin Normal file
View file

@ -0,0 +1,6 @@
<FORM METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="proto" VALUE="<% request.proto %>">
<INPUT TYPE="HIDDEN" NAME="name" VALUE="<% request.name %>"><BR>
<% this.skin as="editor" width="70" height="20" wrap="OFF" %><BR>
<% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %>
</FORM>

13
code/Skin/macros.js Normal file
View file

@ -0,0 +1,13 @@
/**
* macro rendering source of skin
*/
function skin_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputTextarea(this.createInputParam("skin",param));
else
res.write(this.skin);
renderSuffix(param);
}

11
code/Skin/type.properties Normal file
View file

@ -0,0 +1,11 @@
_datasource=antville
_tablename=SKIN
_id=ID
weblog=WEBLOG_ID>weblog.ID
proto=PROTO
name=NAME
skin=SOURCE
creator=CREATOR
createtime=CREATETIME
modified=MODIFYTIME

38
code/SkinMgr/macros.js Normal file
View file

@ -0,0 +1,38 @@
/**
* macro renders filebased-skins as list
*/
function skins_macro(param) {
renderPrefix(param);
for (var i in app.skinfiles) {
res.write("<B>" + i + "</B><BR>");
for (var j in app.skinfiles[i]) {
res.write("&bull;&nbsp;");
res.write("<A HREF=\"" + this.href() + "?proto=" + i + "&name=" + j + "\">");
res.write(j);
res.write("</A><BR>");
}
}
renderSuffix(param);
}
/**
* macro calls a form-skin for editing a skin-source
*/
function skineditor_macro(param) {
renderPrefix(param);
if (req.data.proto && req.data.name) {
// user wants to edit a skin, so we try to get it:
var currProto = this.__parent__.skinmanager.get(req.data.proto);
if (currProto && currProto.get(req.data.name)) {
var currSkin = currProto.get(req.data.name);
currSkin.renderSkin("edit");
} else {
var newSkin = new skin();
newSkin.renderSkin("edit");
}
}
renderSuffix(param);
}

14
code/SkinMgr/main.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.href());
else if (req.data.submit == "save")
this.saveSkin();
res.skin = "main";
res.title = "Antville - " + this.__parent__.title;
res.head = this.__parent__.renderSkinAsString("style");
res.body = this.__parent__.renderSkinAsString("header");
res.body += this.renderSkinAsString("main");

7
code/SkinMgr/main.skin Normal file
View file

@ -0,0 +1,7 @@
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD NOWRAP><FONT SIZE="-1"><% this.skins %></FONT></TD>
<TD WIDTH="20" NOWRAP>&nbsp;</TD>
<TD VALIGN="TOP" NOWRAP><% this.skineditor %></TD>
</TR>
</TABLE>

View file

@ -0,0 +1,26 @@
/**
* function evaluates skin
*/
function saveSkin() {
if (req.data.proto && req.data.name) {
var currProto = this.__parent__.skinmanager.get(req.data.proto);
if (currProto) {
var currSkin = currProto.get(req.data.name);
}
if (!currSkin && req.data.skin) {
var currSkin = new skin();
currSkin.creator = user;
currSkin.createtime = new Date();
currSkin.name = req.data.name;
currSkin.proto = req.data.proto;
this.__parent__.skinmanager.add(currSkin);
} else if (!req.data.skin) {
currProto.remove(currSkin);
}
if (req.data.skin)
currSkin.skin = req.data.skin;
res.message = "Changes were saved successfully!";
}
res.redirect(this.href() + "?proto=" + req.data.proto + "&name=" + req.data.name);
}

View file

@ -0,0 +1,14 @@
/**
* function checks if user is allowed to edit skins of this weblog
*/
function checkPermissions() {
if (!user.uid) {
res.message = "Please login before!";
user.cache.referer = this.href();
res.redirect(this.__parent__.members.href("login"));
} else if (this.__parent__.owner != user) {
res.message = "Sorry, you're not allowed to edit skins";
res.redirect(this.href());
}
}

View file

@ -0,0 +1 @@
<% this.link to="main" text="comment" %>&nbsp;(<% this.commentcounter no=" threads" one=" thread" more=" threads" %>)

14
code/Story/delete.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "delete")
this.weblog.deleteStory(this);
else if (req.data.submit == "cancel")
res.redirect(this.weblog.href("main"));
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("delete");

4
code/Story/delete.skin Normal file
View file

@ -0,0 +1,4 @@
<FORM METHOD="POST">
<P>Warning! You are about to delete the Story <B><% this.title %></B>! Be aware of the fact that there is no "undo", so if you klick on delete here the story will be gone forever!</P>
<P><% this.input type="button" value="delete" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

14
code/Story/edit.hac Normal file
View file

@ -0,0 +1,14 @@
// check if user is logged in and is the owner of this weblog
this.checkPermissions();
if (req.data.submit == "cancel")
res.redirect(this.weblog.href());
this.evalStory();
res.skin = "main";
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("edit");

6
code/Story/edit.skin Normal file
View file

@ -0,0 +1,6 @@
<FORM METHOD="POST">
<P>Title: <% this.title as="editor" %></P>
<P>Text: <% this.text as="editor" width="40" height="10" %></P>
<P>is online: <% this.online as="editor" %></P>
<P><% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

View file

@ -0,0 +1,8 @@
/**
* function filters comments
* only toplevel-comments should appear as subnodes of story
*/
function filter() {
this.subnodeRelation = "WHERE STORY_ID = " + this.__id__ + " AND PARENT_ID is null ORDER BY CREATETIME asc";
}

1
code/Story/login.skin Normal file
View file

@ -0,0 +1 @@
<P><% weblog.loginlink text="login to add your comment!" %></P>

195
code/Story/macros.js Normal file
View file

@ -0,0 +1,195 @@
/**
* macro rendering title of story
*/
function title_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("title",param));
else
res.write(this.title);
renderSuffix(param);
}
/**
* macro rendering text of story
*/
function text_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputTextarea(this.createInputParam("text",param));
else {
var text = createSkin(format(this.text));
this.renderSkin(text);
}
renderSuffix(param);
}
/**
* macro rendering online-status of story
*/
function online_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputCheckbox(this.createInputParam("online",param));
else
res.write(parseInt(this.online,10) ? "yes" : "no");
renderSuffix(param);
}
/**
* macro rendering createtime of story
*/
function createtime_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderDateDropdown(this.createInputParam("createtime",param));
else {
res.write(param.format ? this.createtime.format(param.format) : this.createtime.format());
}
renderSuffix(param);
}
/**
* macro rendering a link to edit
* if user is allowed to edit
*/
function editlink_macro(param) {
renderPrefix(param);
if (this.author == user) {
var linkParam = new HopObject();
linkParam.linkto = "edit";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "edit");
else
this.renderImage(param);
this.closeLink();
}
renderSuffix(param);
}
/**
* macro rendering a link to delete
* if user is owner of this story
*/
function deletelink_macro(param) {
renderPrefix(param);
if (this.author == user) {
var linkParam = new HopObject();
linkParam.linkto = "delete";
this.openLink(linkParam);
if (!param.image)
res.write(param.text ? param.text : "delete");
else
this.renderImage(param);
this.closeLink();
}
renderSuffix(param);
}
/**
* macro rendering link to comments
*/
function commentlink_macro(param) {
if (path[path.length-1] != this && this.weblog.hasDiscussions()) {
renderPrefix(param);
this.renderSkin(param.useskin ? param.useskin : "commentlink");
renderSuffix(param);
}
}
/**
* macro renders number of comments
* options: text to use when no comment
* text to use when one comment
* text to use when more than one comment
*/
function commentcounter_macro(param) {
if (this.weblog.hasDiscussions()) {
renderPrefix(param);
this.filter();
if (this.count() == 0) {
res.write(this.count() + (param.no ? param.no : " threads"));
} else if (this.count() == 1) {
res.write(this.count() + (param.one ? param.one : " thread"));
} else if (this.count() > 1) {
res.write(this.count() + (param.more ? param.more : " threads"));
}
renderSuffix(param);
}
}
/**
* macro loops over comments and renders them
*/
function comments_macro(param) {
if (this.weblog.hasDiscussions() && this.count()) {
renderPrefix(param);
for (var i=0;i<this.size();i++) {
this.get(i).renderSkin("toplevel");
}
renderSuffix(param);
}
}
/**
* macro checks if user is logged in and not blocked
* if true, render form to add a comment
*/
function commentform_macro(param) {
if (this.weblog.hasDiscussions()) {
renderPrefix(param);
if (user.uid && !user.isBlocked()) {
var c = new comment();
c.renderSkin("edit");
// this.renderSkin(param.useskin ? param.useskin : "commentform");
} else if (!user.isBlocked())
res.write("<A HREF=\"" + this.weblog.members.href("login") + "\">Login to add your comment</A>");
renderSuffix(param);
}
}
/**
* macro renders an image out of image-pool
* either as plain image or as image-link
* overrideable parameters: width,height,alttext,border
* additional parameters: align, valign
*/
function image_macro(param) {
if (param && param.name) {
renderPrefix(param);
this.weblog.renderImage(param);
/*
if (param.linkto)
this.openLink(param);
var img = this.weblog.images.get(param.name);
if (img) {
res.write("<IMG SRC=\"" + getProperty("imgUrl") + this.weblog.alias + "/" + img.filename + "." + img.fileext + "\"");
res.write(" WIDTH=\"" + (param.width ? param.width : img.width) + "\"");
res.write(" HEIGHT=\"" + (param.height ? param.height : img.height) + "\"");
res.write(" ALT=\"" + (param.alttext ? param.alttext : img.alttext) + "\"");
if (param.align)
res.write(" ALIGN=\"" + param.align + "\"");
if (param.valign)
res.write(" VALIGN=\"" + param.valign + "\"");
res.write(" BORDER=\"" + (param.border ? param.border : 0) + "\">");
}
if (param.linkto)
this.closeLink(param);
*/
renderSuffix(param);
}
}

11
code/Story/main.hac Normal file
View file

@ -0,0 +1,11 @@
this.filter();
res.skin = "main";
if (req.data.text && this.weblog.hasDiscussions())
this.addComment();
res.title = "Antville - " + this.weblog.title;
res.head = this.weblog.renderSkinAsString("style");
res.body = this.weblog.renderSkinAsString("header");
res.body += this.renderSkinAsString("main");

6
code/Story/main.skin Normal file
View file

@ -0,0 +1,6 @@
<P><FONT SIZE="-2"><% this.createtime format="EEEE, dd.MM.yyyy" %></FONT><BR>
<B><% this.title %></B><BR>
<% this.text %></P>
<HR>
<% this.comments %>
<% this.commentform %>

View file

@ -0,0 +1,57 @@
/**
* check if story is ok; if true, save changed story
*/
function evalStory() {
if (req.data.text) {
this.title = req.data.title;
this.text = req.data.text;
this.online = req.data.online;
this.modifytime = new Date();
res.message = "The story was updated successfully!";
res.redirect(this.weblog.href());
} else
res.message = "You need at least some text!";
}
/**
* function returns true/false whether story is online or not
*/
function isOnline() {
if (parseInt(this.online,10))
return true;
return false;
}
/**
* function evaluates comment and adds it if ok
*/
function addComment() {
if (user.uid && !user.isBlocked()) {
var c = new comment();
c.title = req.data.title;
c.text = req.data.text;
c.weblog = this.weblog;
c.story = this;
c.createtime = new Date();
c.author = user;
c.online = 1;
c.ipadress = req.data.http_remotehost;
this.add(c);
}
res.redirect(this.href());
}
/**
* function deletes a comment
*/
function deleteComment(currComment) {
currComment.setParent(this);
this.remove(currComment);
res.message = "The comment was deleted successfully!";
res.redirect(this.href());
}

4
code/Story/preview.skin Normal file
View file

@ -0,0 +1,4 @@
<P><FONT SIZE="-2"><% this.createtime format="EEEE, dd.MM.yyyy, HH:mm" suffix=" Uhr"%></FONT><BR>
<SPAN CLASS="title"><% this.title %></SPAN><BR>
<% this.text %>
<% this.commentlink prefix="<BR>" %><% this.editlink prefix="&nbsp;&nbsp;" %><% this.deletelink prefix="&nbsp;&nbsp;" %></P>

View file

@ -0,0 +1,10 @@
/**
* check if user is allowed to edit this story
*/
function checkPermissions() {
if (this.author != user || user.isBlocked()) {
res.message = "Sorry, you're not allowed to edit this story!";
res.redirect(this.weblog.href());
}
}

View file

@ -0,0 +1,15 @@
_datasource=antville
_tablename=STORY
_subnodes=<comment.STORY_ID
_subnodes.order=CREATETIME ASC
_id=ID
weblog=WEBLOG_ID>weblog.ID
day=DAY
title=TITLE
text=TEXT
online=ISONLINE
# postdate=POSTDATE
author=AUTHOR>user.ID
createtime=CREATETIME
modifytime=MODIFYTIME

9
code/User/edit.skin Normal file
View file

@ -0,0 +1,9 @@
<FORM METHOD="POST">
<P>Old password:&nbsp;<% this.input type="password" name="oldpwd" %><BR>
New password: <% this.input type="password" name="newpwd1" %><BR>
Confirm password: <% this.input type="password" name="newpwd2" %><BR>
URL:&nbsp;<% currentUser.url as="editor" %><BR>
eMail:&nbsp;<% this.email as="editor" %><BR>
Description:&nbsp;<% this.description as="editor" %><BR>
<% this.input type="button" value="save" %>&nbsp;<% this.input type="button" value="cancel" %></P>
</FORM>

64
code/User/macros.js Normal file
View file

@ -0,0 +1,64 @@
/**
* macro rendering username
*/
function name_macro(param) {
renderPrefix(param);
res.write(this.name);
renderSuffix(param);
}
/**
* macro rendering password
*/
function password_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputPassword(this.createInputParam("password",param));
else
res.write(this.password);
renderSuffix(param);
}
/**
* macro rendering URL
*/
function url_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("url",param));
else
res.write(this.url);
renderSuffix(param);
}
/**
* macro rendering email
*/
function email_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputText(this.createInputParam("email",param));
else
res.write(this.email);
renderSuffix(param);
}
/**
* macro rendering description
*/
function description_macro(param) {
renderPrefix(param);
if (param.as == "editor")
this.renderInputTextarea(this.createInputParam("description",param));
else
res.write(this.description);
renderSuffix(param);
}

View file

@ -0,0 +1,37 @@
/**
* send a mail to confirm registration
*/
function sendConfirmationMail() {
var mail = new Mail();
mail.setFrom(getProperty("adminEmail"));
mail.setTo(user.email);
mail.setSubject("Welcome to Antville!");
mail.setText(this.renderSkinAsString("regConfirm"));
mail.send();
}
/**
* check if user is blocked
*/
function isBlocked() {
if (parseInt(user.blocked,10)) {
res.message = "Sorry, you were blocked by an Administrator!";
return true;
} else
return false;
}
/**
* check if user owns a weblog
* returns true|false
*/
function getWeblog() {
if (user.weblog)
return true;
return false;
}

Some files were not shown because too many files have changed in this diff Show more