changed: db: table item: url_subject into url

changed: item.url_subject into item.url
changed: a new table: content
         with: id, subject, content, content_type
         (those from the item table)
         it helps to create hard links


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@466 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2008-12-14 05:28:28 +00:00
parent 023faa66fc
commit 86f28faf8d
10 changed files with 389 additions and 165 deletions

View File

@ -1,5 +1,5 @@
CC = g++
o = dir.o data.o content.o log.o sessionmanager.o requestcontroller.o dircontainer.o session.o main.o done.o request.o misc.o templates.o httpsimpleparser.o db.o error.o config.o confparser.o ezc.o
o = dir.o data.o content.o log.o sessionmanager.o requestcontroller.o dircontainer.o session.o main.o done.o request.o misc.o templates.o httpsimpleparser.o db.o error.o db_itemcolumns.o config.o confparser.o ezc.o
CFLAGS = -Wall -pedantic -g -I/usr/local/include -L/usr/local/lib
name = cmslu.fcgi
@ -35,13 +35,13 @@ templates.o: core/templates.cpp core/templates.h core/../../ezc/src/ezc.h core
httpsimpleparser.o: core/httpsimpleparser.cpp core/httpsimpleparser.h
db.o: core/db.cpp core/db.h core/log.h core/item.h core/misc.h core/error.h core/dircontainer.h
error.o: core/error.cpp core/error.h core/log.h
db_itemcolumns.o: core/db_itemcolumns.cpp core/db.h core/log.h core/item.h core/misc.h core/error.h core/dircontainer.h
config.o: core/config.cpp core/config.h core/../confparser/confparser.h core/error.h core/log.h core/data.h core/misc.h core/item.h core/dir.h core/db.h core/dircontainer.h
confparser.o: confparser/confparser.cpp confparser/confparser.h
ezc.o: ../ezc/src/ezc.cpp ../ezc/src/ezc.h
clean:
rm -f *.o
rm -f $(name)

View File

@ -175,12 +175,12 @@ void Content::PrepareUrlSubject(Item & item)
{
SetUrlSubjectFromSubject(item);
if( StandardFunction(item.url_subject) != Request::err404 )
if( StandardFunction(item.url) != Request::err404 )
{
// names of functions should not begin with an underscore '_'
// and we can simply add one '_' at the beginning
// and the name will be unique
item.url_subject.insert(item.url_subject.begin(), '_');
item.url.insert(item.url.begin(), '_');
}
}
@ -265,12 +265,12 @@ void Content::MakeGet()
}
if( request.get_table[get_index].empty() )
// we do not have an empty url_subject
// we do not have an empty url
// err404 at the end
return;
// if we want to search by url_subject then request.get_table[get_index] should not be empty
item.url_subject = request.get_table[get_index++];
// if we want to search by url then request.get_table[get_index] should not be empty
item.url = request.get_table[get_index++];
db.GetItems(request.item_table, item);
if( request.item_table.empty() )
@ -306,7 +306,7 @@ void Content::AppendCurDir(std::string & dir)
for(a=0 ; a<request.cur_dir_table.size() ; ++a)
{
dir += request.cur_dir_table[a].url_subject;
dir += request.cur_dir_table[a].url;
dir += '/';
}
}
@ -331,7 +331,7 @@ void Content::MakeShowItemById()
request.result = Request::redirect;
std::string path;
data.dir.MakePath(request.item_table[0].parent_id, path);
request.str = data.base_url + path + request.item_table[0].url_subject;
request.str = data.base_url + path + request.item_table[0].url;
}
}
}
@ -355,7 +355,7 @@ void Content::MakeDelItem()
request.CopyFirstItem();
request.session->item = request.item;
if( db.DelItem( request.item.id ) )
if( db.DelItem( request.item ) )
{
request.session->done = Done::deleted_item;
request.session->done_status = Error::ok;
@ -402,7 +402,7 @@ void Content::MakeLogout()
request.str = data.base_url + path;
if( !request.item_table.empty() )
request.str += request.item_table[0].url_subject;
request.str += request.item_table[0].url;
request.session->done = Done::loggedout;
request.session->done_timer = 2;

View File

@ -186,6 +186,7 @@ return res;
}
void Db::ClearResult(PGresult * r)
{
if( r )
@ -263,7 +264,7 @@ appendix[0] = 0;
std::ostringstream query;
// this Escape can be put at the beginning (performance)
query << "select id from core.item where url_subject='" << Escape(item.url_subject) << appendix << "' and parent_id='" << item.parent_id << "';";
query << "select id from core.item where url='" << Escape(item.url) << appendix << "' and parent_id='" << item.parent_id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_TUPLES_OK);
@ -274,7 +275,7 @@ appendix[0] = 0;
}
else
{
item.url_subject += appendix;
item.url += appendix;
is_that_url = false;
}
@ -304,15 +305,15 @@ void Db::CheckAllUrlSubjectModifyItem(Item & item)
try
{
std::ostringstream query;
query << "update core.item set url_subject=";
query << "update core.item set url=";
// url_subject
// url
if( AddItemCreateUrlSubject(item) )
query << '\'' << Escape(item.url_subject) << '\'';
query << '\'' << Escape(item.url) << '\'';
else
{
query << '\'' << item.id << '\'';
item.url_subject.clear();
item.url.clear();
}
query << " where id='" << item.id << "';";
@ -339,7 +340,7 @@ void Db::CheckAllUrlSubject()
{
AssertConnection();
std::ostringstream query, query2;
query << "select id, subject from core.item where url_subject is null or url_subject=''";
query << "select item.id, subject from core.item left join core.content on item.content_id = content.id where url is null or url=''";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_TUPLES_OK);
@ -350,7 +351,7 @@ void Db::CheckAllUrlSubject()
for(int i = 0 ; i<rows ; ++i)
{
item.id = atol( AssertValue(r, i, cid) );
item.id = atol( AssertValue(r, i, cid) );
item.subject = AssertValue(r, i, csubject);
CheckAllUrlSubjectModifyItem(item);
@ -387,8 +388,7 @@ return res;
}
Error Db::AddItem(Item & item)
Error Db::AddItemIntoItem(Item & item)
{
PGresult * r = 0;
Error result = Error::ok;
@ -398,34 +398,29 @@ Error Db::AddItem(Item & item)
{
AssertConnection();
std::ostringstream query;
query << "insert into core.item (subject, content, url_subject, type, parent_id) values (";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.content) << "', ";
query << "insert into core.item (user_id, group_id, privileges, type, parent_id, content_id, url) values (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "', ";
query << '\'' << item.content_id << "', ";
// url_subject
url_without_id = AddItemCreateUrlSubject(item);
if( url_without_id )
{
query << '\'' << Escape(item.url_subject) << "', ";
}
query << '\'' << Escape(item.url) << "');";
else
{
query << "currval('core.item_id_seq')" << ", ";
}
query << "currval('core.item_id_seq')" << ");";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "' ";
query << ");";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
item.id = AssertCurrval("core.item_id_seq");
if( !url_without_id )
ToString(item.url_subject, item.id);
ToString(item.url, item.id);
}
catch(const Error & e)
@ -439,7 +434,56 @@ return result;
}
Error Db::EditItem(Item & item, bool with_subject)
Error Db::AddItemIntoContent(Item & item)
{
PGresult * r = 0;
Error result = Error::ok;
try
{
AssertConnection();
std::ostringstream query;
query << "insert into core.content (subject, content, content_type) values (";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "');";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
item.content_id = AssertCurrval("core.content_id_seq");
}
catch(const Error & e)
{
result = e;
}
ClearResult(r);
return result;
}
Error Db::AddItem(Item & item)
{
Error result = AddItemIntoContent(item);
if( result == Error::ok )
result = AddItemIntoItem(item);
return result;
}
Error Db::EditItemInItem(Item & item, bool with_subject)
{
PGresult * r = 0;
Error result = Error::ok;
@ -449,41 +493,35 @@ Error Db::EditItem(Item & item, bool with_subject)
{
AssertConnection();
std::ostringstream query;
query << "update core.item set (";
query << "update core.item set (user_id, group_id, privileges, type, parent_id,";
if( with_subject )
query << "subject, url_subject, ";
query << " url";
query << "content, type, parent_id) = (";
query << ") = (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "' ";
if( with_subject )
{
query << '\'' << Escape(item.subject) << "', ";
// url_subject
url_without_id = AddItemCreateUrlSubject(item);
if( url_without_id )
{
query << '\'' << Escape(item.url_subject) << "', ";
}
query << ", '" << Escape(item.url) << "'";
else
{
query << '\'' << item.id << "', ";
}
query << ", '" << item.id << "'";
}
query << '\'' << Escape(item.content) << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "' ";
query << ") where id='" << item.id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
if( with_subject && !url_without_id )
ToString(item.url_subject, item.id);
ToString(item.url, item.id);
}
catch(const Error & e)
{
@ -497,16 +535,62 @@ return result;
Error Db::EditItemInContent(Item & item)
{
PGresult * r = 0;
Error result = Error::ok;
try
{
AssertConnection();
std::ostringstream query;
query << "update core.content set (subject, content, content_type) = (";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "' ";
query << ") where id='" << item.content_id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
result = e;
}
ClearResult(r);
return result;
}
Error Db::EditItem(Item & item, bool with_subject)
{
Error result = EditItemInContent(item);
if( result == Error::ok )
result = EditItemInItem(item, with_subject);
return result;
}
PGresult * Db::GetItemsQuery(Item & item_ref)
{
std::ostringstream query;
query << "select * from core.item where type!='0' and parent_id='" << item_ref.parent_id << "'";
query << "select * from core.item left join core.content on item.content_id = content.id where type!='0' and parent_id='" << item_ref.parent_id << "'";
if( item_ref.id != -1 )
query << " and id='" << item_ref.id << "'";
query << " and item.id='" << item_ref.id << "'";
if( !item_ref.url_subject.empty() )
query << " and url_subject='" << Escape(item_ref.url_subject) << "'";
if( !item_ref.url.empty() )
query << " and url='" << Escape(item_ref.url) << "'";
query << ';';
@ -557,7 +641,7 @@ void Db::GetItem(std::vector<Item> & item_table, long id)
AssertConnection();
std::ostringstream query;
query << "select * from core.item where type='1' and id='" << id << "';";
query << "select * from core.item left join core.content on item.content_id = content.id where type='1' and item.id='" << id << "';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_TUPLES_OK);
@ -585,9 +669,11 @@ void Db::GetItem(std::vector<Item> & item_table, long id)
}
bool Db::DelItem(long id)
bool Db::DelItemDelItem(const Item & item)
{
long rows = 0;
long rows = 0;
PGresult * r = 0;
try
@ -595,7 +681,7 @@ bool Db::DelItem(long id)
AssertConnection();
std::ostringstream query;
query << "delete from core.item where type='1' and id='" << id << "';";
query << "delete from core.item where id='" << item.id << "';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_COMMAND_OK);
@ -607,6 +693,9 @@ bool Db::DelItem(long id)
if( rows > 1 )
log << log1 << "Db: more than one item were deleted" << logend;
else
if( rows == 0 )
log << log1 << "Db: no item has been deleted" << logend;
}
}
catch(const Error &)
@ -619,6 +708,93 @@ return rows != 0;
}
void Db::DelItemDelContent(const Item & item)
{
PGresult * r = 0;
try
{
AssertConnection();
std::ostringstream query;
query << "delete from core.content where id='" << item.content_id << "';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_COMMAND_OK);
const char * crows = PQcmdTuples(r);
if( crows )
{
long rows = atol(crows);
if( rows > 1 )
log << log1 << "Db: more than one content were deleted" << logend;
else
if( rows == 0 )
log << log1 << "Db: no content has been deleted" << logend;
}
}
catch(const Error &)
{
}
ClearResult(r);
}
Error Db::DelItemCountContents(const Item & item, long & contents)
{
Error result = Error::ok;
PGresult * r = 0;
try
{
AssertConnection();
std::ostringstream query;
query << "select count('id') from core.item where content_id='" << item.content_id << "';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_TUPLES_OK);
contents = atol( AssertValue(r, 0, 0) );
log << log1 << "counters: " << contents << logend; // !!
}
catch(const Error & e)
{
result = e;
}
ClearResult(r);
return result;
}
bool Db::DelItem(const Item & item)
{
long contents;
Error result = DelItemCountContents(item, contents);
if( result == Error::ok && contents == 1 )
DelItemDelContent(item);
return DelItemDelItem(item);
}
void Db::GetDirs(DirContainer & dir_table)
{
PGresult * r = 0;
@ -628,7 +804,7 @@ void Db::GetDirs(DirContainer & dir_table)
AssertConnection();
std::ostringstream query;
query << "select * from core.item where type='0';";
query << "select * from core.item left join core.content on item.content_id = content.id where type='0';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_TUPLES_OK);

122
core/db.h
View File

@ -29,84 +29,64 @@
class Db
{
public:
Db();
~Db();
void Init(const std::string & database, const std::string & user, const std::string & pass);
bool CheckUser(std::string & login, std::string & password, long & user_id);
Error AddItem(Item & item);
Error EditItem(Item & item, bool with_subject = true);
void CheckAllUrlSubject();
void GetItems(std::vector<Item> & item_table, Item & item_ref);
void GetItem(std::vector<Item> & item_table, long id);
bool DelItem(const Item & item);
void GetDirs(DirContainer & dir_table);
protected:
PGconn * pg_conn;
std::string db_database, db_user, db_pass;
public:
Db();
~Db();
void Init(const std::string & database, const std::string & user, const std::string & pass);
void Connect();
void Close();
void AssertConnection();
std::string Escape(const std::string & s);
std::string Escape(const char * s);
PGresult * AssertQuery(const std::string & q);
void AssertResultStatus(PGresult * r, ExecStatusType t);
static int AssertColumn(PGresult * r, const char * column_name);
static const char * AssertValue(PGresult * r, int row, int col);
void ClearResult(PGresult * r);
bool CheckUser(std::string & login, std::string & password, long & user_id);
long AssertCurrval(const char * table);
bool AddItemCreateUrlSubject(Item & item);
Error AddItem(Item & item);
Error EditItem(Item & item, bool with_subject = true);
void CheckAllUrlSubjectModifyItem(Item & item);
void CheckAllUrlSubject();
PGresult * GetItemsQuery(Item & item_ref);
void GetItems(std::vector<Item> & item_table, Item & item_ref);
void GetItem(std::vector<Item> & item_table, long id);
bool DelItem(long id);
void GetDirs(DirContainer & dir_table);
struct ItemColumns
{
int id, subject, content, url_subject, type, parent_id, default_item;
void SetColumns(PGresult * r)
{
id = Db::AssertColumn(r, "id");
subject = Db::AssertColumn(r, "subject");
content = Db::AssertColumn(r, "content");
url_subject = Db::AssertColumn(r, "url_subject");
type = Db::AssertColumn(r, "type");
parent_id = Db::AssertColumn(r, "parent_id");
default_item = Db::AssertColumn(r, "default_item");
}
void SetItem(PGresult * r, long row, Item & item)
{
item.id = atol( Db::AssertValue(r, row, id) );
item.subject = Db::AssertValue(r, row, subject);
item.content = Db::AssertValue(r, row, content);
item.url_subject = Db::AssertValue(r, row, url_subject);
item.type = static_cast<Item::Type>( atoi( Db::AssertValue(r, row, type) ) );
item.parent_id = atol( Db::AssertValue(r, row, parent_id) );
item.default_item = atol( Db::AssertValue(r, row, default_item) );
}
void Connect();
void Close();
void AssertConnection();
std::string Escape(const std::string & s);
std::string Escape(const char * s);
PGresult * AssertQuery(const std::string & q);
void AssertResultStatus(PGresult * r, ExecStatusType t);
static int AssertColumn(PGresult * r, const char * column_name);
static const char * AssertValue(PGresult * r, int row, int col);
void ClearResult(PGresult * r);
long AssertCurrval(const char * table);
bool AddItemCreateUrlSubject(Item & item);
};
Error AddItemIntoContent(Item & item);
Error AddItemIntoItem(Item & item);
Error EditItemInItem(Item & item, bool with_subject);
Error EditItemInContent(Item & item);
void CheckAllUrlSubjectModifyItem(Item & item);
PGresult * GetItemsQuery(Item & item_ref);
bool DelItemDelItem(const Item & item);
void DelItemDelContent(const Item & item);
Error DelItemCountContents(const Item & item, long & contents);
struct ItemColumns
{
int id, user_id, group_id, privileges, url, type, parent_id, content_id, default_item, subject, content, content_type;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);
};
}; // class Db

46
core/db_itemcolumns.cpp Executable file
View File

@ -0,0 +1,46 @@
#include "db.h"
void Db::ItemColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id"); // !! why item.id doesn't work?
user_id = PQfnumber(r, "user_id");
group_id = PQfnumber(r, "group_id");
privileges = PQfnumber(r, "privileges");
url = PQfnumber(r, "url");
type = PQfnumber(r, "type");
parent_id = PQfnumber(r, "parent_id");
content_id = PQfnumber(r, "content_id");
default_item = PQfnumber(r, "default_item");
subject = PQfnumber(r, "subject");
content = PQfnumber(r, "content");
content_type = PQfnumber(r, "content_type");
}
void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
{
if( id != -1 ) item.id = atol( Db::AssertValue(r, row, id) );
if( user_id != -1 ) item.user_id = atol( Db::AssertValue(r, row, user_id) );
if( group_id != -1 ) item.group_id = atol( Db::AssertValue(r, row, group_id) );
if( privileges != -1 ) item.privileges = atoi( Db::AssertValue(r, row, privileges) );
if( url != -1 ) item.url = Db::AssertValue(r, row, url);
if( type != -1 ) item.type = static_cast<Item::Type>( atoi( Db::AssertValue(r, row, type) ) );
if( parent_id != -1 ) item.parent_id = atol( Db::AssertValue(r, row, parent_id) );
if( content_id != -1 ) item.content_id = atol( Db::AssertValue(r, row, content_id) );
if( default_item != -1 ) item.default_item = atol( Db::AssertValue(r, row, default_item) );
if( subject != -1 ) item.subject = Db::AssertValue(r, row, subject);
if( content != -1 ) item.content = Db::AssertValue(r, row, content);
if( content_type != -1 ) item.content_type = atoi( Db::AssertValue(r, row, content_type) );
}

View File

@ -35,7 +35,7 @@ bool Dir::GetDir(const std::string & name, long parent, Item ** item)
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
for( ; i!=dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
if( i->second->url_subject == name )
if( i->second->url == name )
{
*item = &(*i->second);
return true;
@ -164,7 +164,7 @@ DirContainer::Iterator i;
id = i->parent_id;
path.insert(path.begin(), '/');
path.insert(0, i->url_subject);
path.insert(0, i->url);
}
}

View File

@ -19,9 +19,19 @@ struct Item
{
long id;
long user_id;
long group_id;
int privileges;
std::string subject;
std::string content;
std::string url_subject;
std::string url;
int content_type;
enum Type
{
@ -41,6 +51,9 @@ long parent_id;
long default_item;
// used by the database
long content_id;
Item()
{
@ -52,13 +65,22 @@ Item()
void Clear()
{
id = -1;
user_id = -1;
group_id = -1;
privileges = 0;
subject.clear();
content.clear();
url_subject.clear();
url.clear();
content_type = 0;
type = none;
parent_id = -1;
default_item = -1;
content_id = -1;
}

View File

@ -35,7 +35,7 @@ void SetUrlSubjectFromSubject(Item & item)
{
std::string::iterator i;
item.url_subject.clear();
item.url.clear();
for(i = item.subject.begin(); i!=item.subject.end() ; ++i)
{
@ -47,18 +47,18 @@ std::string::iterator i;
(c == '(' || c == ')' || c == '.' || c == ',' || c == '_' )
)
{
item.url_subject += c;
item.url += c;
}
else
item.url_subject += '_';
item.url += '_';
}
if( item.url_subject.empty() )
item.url_subject = "bez_nazwy";
if( item.url.empty() )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
else
if( item.url_subject[0] >= '0' && item.url_subject[0] <= '9' )
// url_subject must begin with a letter
item.url_subject.insert(item.url_subject.begin(), '_');
if( item.url[0] >= '0' && item.url[0] <= '9' )
// url must begin with a letter
item.url.insert(item.url.begin(), '_');
}

View File

@ -59,7 +59,7 @@ struct Request
// what to do
enum Result { err_internal, err404, show_dir, show_item, show_item_by_id, add_item, edit_item, del_item, del_item_confirm, confirm, redirect, logout } result; // zamienic na to_do
//Item item; // bedziemy uzywac tego, item_id i item_url_subject wywalic

View File

@ -148,9 +148,9 @@ void item_content(Info & i)
}
void item_url_subject(Info & i)
void item_url_subject(Info & i) // !! zmienic nazwe
{
i.out << request.item.url_subject;
i.out << request.item.url;
}
@ -190,9 +190,9 @@ i.out << request.session->item.content;
}
void old_item_url_subject(Info & i)
void old_item_url_subject(Info & i) // zmienic nazwe !!
{
i.out << request.session->item.url_subject;
i.out << request.session->item.url;
}
@ -220,7 +220,7 @@ std::vector<Item>::size_type a;
for(a=0 ; a<request.cur_dir_table.size() ; ++a)
{
i.out << request.cur_dir_table[a].url_subject << '/';
i.out << request.cur_dir_table[a].url << '/';
}
}
@ -255,11 +255,11 @@ void dir_subject2(Info & i)
}
}
void dir_url_subject2(Info & i)
void dir_url_subject2(Info & i) // zmienic nazwe
{
if( dir_index < request.dir_table.size() )
{
HtmlSpecial(i.out, request.dir_table[dir_index].url_subject);
HtmlSpecial(i.out, request.dir_table[dir_index].url);
}
}
@ -289,10 +289,10 @@ void item_subject2(Info & i)
}
}
void item_url_subject2(Info & i)
void item_url_subject2(Info & i) // !! zmienic nazwe
{
if( item_index < request.item_table.size() )
HtmlSpecial(i.out, request.item_table[item_index].url_subject);
HtmlSpecial(i.out, request.item_table[item_index].url);
}
void item_content2(Info & i)
@ -336,14 +336,8 @@ void fcurrent_dir(Info & i)
}
void current_dir_part_name(Info & i)
{
if( current_dir_index < request.cur_dir_table.size() )
i.out << request.cur_dir_table[current_dir_index].subject;
}
void current_dir_part_url(Info & i)
void current_dir_part_link(Info & i)
{
std::vector<Item>::size_type a;
@ -351,10 +345,16 @@ void current_dir_part_url(Info & i)
for(a = 0 ; a <= current_dir_index && a < request.cur_dir_table.size() ; ++a)
{
i.out << request.cur_dir_table[a].url_subject << '/';
i.out << request.cur_dir_table[a].url << '/';
}
}
void current_dir_part_url(Info & i)
{
if( current_dir_index < request.cur_dir_table.size() )
i.out << request.cur_dir_table[current_dir_index].url;
}
void edit_item(Info & i)
@ -467,7 +467,7 @@ void Templates::CreateFunctions()
functions.Insert("incorrect_dir", incorrect_dir);
functions.Insert("fcurrent_dir", fcurrent_dir);
functions.Insert("current_dir_part_name", current_dir_part_name);
functions.Insert("current_dir_part_link", current_dir_part_link);
functions.Insert("current_dir_part_url", current_dir_part_url);
functions.Insert("added_item", added_item);