blog_ 매크로 시리즈
-
- 1. 이 패치는...
-
- 2. 사용법
-
-
- 2.1. blog_newpost 매크로
-
- 2.2. blog_calendar 매크로
-
- 2.3. blog_includeorder 매크로
-
- 2.4. blog_includeperiod 매크로
-
- 2.5. blog_listorder 매크로
-
- 2.6. blog_listperiod 매크로
-
- 2.7. blog_prevnext 매크로
-
- 2.8. blog_prevnextmonth 매크로
-
- 2.9. blog_rss 매크로
-
- 2.10. blog_rss 액션
-
3. 소스 수정
-
-
- 3.1. macros/blog_newpost.pl 추가
-
- 3.2. macros/blog_calendar.pl 추가
-
- 3.3. macros/blog_includeorder.pl 추가
-
- 3.4. macros/blog_includeperiod.pl 추가
-
- 3.5. macros/blog_listorder.pl 추가
-
- 3.6. macros/blog_listperiod.pl 추가
-
- 3.7. macros/blog_prevnext.pl 추가
-
- 3.8. macors/blog_prevnextmonth.pl 추가
-
- 3.9. macros/blog_library.pl 추가
-
- 3.10. action/blog_newpost.pl 추가
-
- 3.11. action/comments.pl 수정
-
- 3.12. action/trackback.pl 수정
-
- 3.13. macros/blog_rss.pl 추가
-
- 3.14. action/blog_rss.pl 추가
-
4. 추가 업데이트 내역
-
- 5. 사용자 의견
-
1. 이 패치는...
위키의블로그화프로젝트를 위해 만들어진 매크로들.
2.1. blog_newpost 매크로
<blog_newpost(목차페이지이름)>
- 이 매크로는 해당 목차페이지 안에 있어야 한다.
- 제목과 날짜를 입력하는 폼으로 치환된다.
- 제목과 날짜를 넣고 저장 버튼을 누르면 매크로가 있던 자리에 다음과 같이 추가된다.
* [[/제목]] 날짜
2.2. blog_calendar 매크로
<blog_calendar(목차페이지이름,년,월)>
- "년도"와 "월"은 /Calendar매크로에서와 동일
- 달력을 출력하고, 어떤 날짜에 올라온 포스트가 있을 경우 해당 날짜에는 그 포스트로 가는 링크가 걸린다.
- 한 날짜에 포스트가 둘 이상 올라왔을 경우는 목차에서 제일 위에 있는 포스트에만 링크가 걸린다는 것이 한계.
2.3. blog_includeorder 매크로
See also 다른페이지의내용을포함하여출력하기
<blog_includeorder(목차페이지,시작순서,끝순서)>
- 여기서 "시작순서"와 "끝순서"는 /MostPopular매크로와 동일하다.
- 목차페이지의 내용이 "최근 글 위에" 방식으로 정렬되므로, 순서도 "1"이 제일 최근 글, "-1"이 가장 이전 글이라는 것에 유의.
- 목차페이지에서 시작순서와 끝순서 사이에 해당되는 페이지들을 찾아서 include한다.
2.4. blog_includeperiod 매크로
See also 다른페이지의내용을포함하여출력하기
<blog_includeperiod(목차페이지,시작날짜,끝날짜)>
- "시작날짜"와 "끝날짜"는 "년-월-일"의 형식으로 쓴다.
- 목차페이지에서 시작날짜와 끝날짜 사이의 페이지를 include 한다. (최근 글이 위에 옴)
2.5. blog_listorder 매크로
<blog_listorder(목차페이지,시작순서,끝순서[,날짜출력방식])>
- blog_includeorder 매크로와 유사하나, 각 페이지를 include하는 대신 리스트로 출력한다.
- "날짜출력방식"을 생략하거나 0으로 주면 페이지제목만 표시한다. 음수로 주면 날짜를 제목 왼쪽에, 양수로 주면 날짜를 제목 오른쪽에 표시한다.
2.6. blog_listperiod 매크로
<blog_listperiod(목차페이지,시작날짜,끝날짜[,날짜출력방식])>
- blog_includeperiod 매크로와 유사하나, 각 페이지를 include하는 대신 리스트로 출력한다.
- "날짜출력방식"을 생략하거나 0으로 주면 페이지제목만 표시한다. 음수로 주면 날짜를 제목 왼쪽에, 양수로 주면 날짜를 제목 오른쪽에 표시한다.
2.7. blog_prevnext 매크로
<blog_prevnext(목차페이지)>
2.8. blog_prevnextmonth 매크로
<blog_prevnext>
- 현재 페이지의 이름이 "2005-03"또는 "Diary/2005-03"등과 같이 "년-월"의 형식일 경우, 그 이전 달과 다음 달에 해당하는 페이지의 링크를 출력. 월별로 보는 페이지에서 이동을 쉽게 하게 함.
- 페이지의 이름이 그 외의 경우라면 아무것도 출력하지 않음.
2.9. blog_rss 매크로
<blog_rss(목차페이지[,블로그페이지])>
- 이 매크로가 있는 자리에 XML아이콘과 "Get RSS of 블로그페이지(블로그페이지 인자가 없을 경우 리스트페이지)"라는 링크가 나타난다.
- 이 링크를 클릭하면 목차페이지에 의한 RSS 출력이 나온다. 자세한 것은 blog_rss 액션 참조.
또는
<blog_rss>
<channel>
[ 채널에 관한 엘리멘트들 ]
[ <item>
아이템에 관한 엘리멘트들
</item> ]
</channel>
</blog_rss>
- 목차 페이지에 위와 같이 들어 있으면, RSS 출력의 채널 정보를 위에 적은 것으로 덮어쓸 수 있다.
- 각각의 포스트 페이지에 위와 같이 들어 있으면, RSS 출력의 각 아이템 정보를 덮어 쓸 수 있다.
- 웹브라우저에서 출력할 때는 널스트링으로 치환.
- 정의하는 예
<blog_rss> - 필수
<channel> - 필수
<title>블로그제목</title> --+
<link>http://...블로그주소</link> +-- 이 부분은 채널에 관한 정보. (생략 가능)
<description>블로그 설명</description> --+ 채널에 관한 정보는 목차페이지에 있을 때만 의미가 있다.
<item> --+
<author>저자</author> +-- 이것은 아이템에 관한 정보. (생략 가능)
</item> --+ 목차페이지에 있는 경우는, RSS의 각 아이템에 일괄 적용된다.
포스트 페이지에 있는 경우는, 그 페이지에 해당하는 아이템에만 적용된다.
</channel> - 필수
</blog_rss> - 필수
- 주의 : 아이템에 관한 정보만 넣을 때도 꼭 위와 같은 형식으로 channel 태그도 써 주어야 함.
2.10. blog_rss 액션
wiki.pl?action=blog_rss&listpage=목차페이지[&blogpage=블로그페이지][&items=아이템갯수]
- 블로그페이지에 대한 RSS를 출력한다.
- 이 RSS는 action=rss 를 했을 때 나오는 RSS와는 다음과 같이 다르다.
- 목차페이지에 있는 리스트만을 대상으로 RSS 목록을 작성한다. 모든 페이지에 대해 목록을 작성하는 게 아니다.
- 목차페이지에 있는 리스트의 순서대로 RSS목록을 작성한다. 각각의 포스트 페이지가 새로 수정되더라도 반영되지 않는다.
- blogpage - 이 인자가 있는 경우, RSS의 사이트링크는 그 페이지로 걸린다. 없을 경우는 그냥 wiki.pl로 걸린다.
- items - 이 인자가 있는 경우, 그 갯수만큼의 페이지의 목록을 작성한다. 기본값은 15개.
- 이 패치에서 출력하는 RSS는 (주인장이 따로 RSS 스펙에 대해 공부하지 않았기 때문에) 태터툴즈와 이글루스의 출력을 참조하였다. 다만 태터나 이글루스와 비교해서 다음의 항목이 좀 다르다. 일종의 한계라고나 할까.
- 사이트 전체에 대해
- 사이트의 설명(<description>)은 config 파일의 $SiteDescription 변수의 내용을 그냥 쓴다. (즉 한 위키에 블로그가 여럿 있더라도 각각의 RSS의 설명이 동일하다.
- 언어(<language>) 항목은 그냥 "ko"로 못박았다.
- 각각의 글에 대한 <item>항목의 경우
- <category> 항목이 안 나온다. (카테고리를 지정할 방법이 없다)
- <author> 는 목차페이지를 마지막으로 수정한 사람이 나온다. (각 글의 저자를 뽑아낼 방법이 없다)
- &tl;pubDate> 는 각 페이지가 처음 생성된 시각을 출력한다.
- 따라서, 위에 적은 항목들의 값이 맘에 안 들 경우는 blog_rss 매크로를 사용해서 자신이 직접 위 항목들을 지정해 줄 수 있다. 위의 blog_rss 매크로를 참조.
- 일단 RSS를 출력하면 이 출력은 TempDir (주로 DateDir/temp) 에 캐쉬되었다가 다음에 RSS 출력할 때 사용된다. 사이트에 변경이 생기면 (정확히는 rclog 파일이 갱신되면) 다음번 RSS 출력시 새로 업데이트한다.
3. 소스 수정
3.1. macros/blog_newpost.pl 추가
sub blog_newpost {
my ($txt) = @_;
$txt =~ s/\&__LT__;blog_newpost\((.+)\)\&__GT__;/&MacroBlogNewPost($1)/gei;
return $txt;
}
sub MacroBlogNewPost {
use strict;
my ($id) = @_;
my $txt;
$id = &RemoveLink($id);
$id = &FreeToNormal($id);
if (my $temp = &ValidId($id)) {
return "<font color='red'>$temp</font>";
}
my ($readonly_true, $readonly_style, $readonly_msg);
my ($title_field, $date_field, $submit_button);
if (!&UserCanEdit($id,1)) {
$readonly_true = "true";
$readonly_style = "background-color: #f0f0f0;";
$readonly_msg = T('Editing Denied');
$submit_button = "";
$title_field = $q->textfield(-name=>"title",
-class=>"comments",
-size=>"50",
-maxlength=>"100",
-readonly=>"$readonly_true",
-style=>"$readonly_style",
-default=>"$readonly_msg");
$date_field = $q->textfield(-name=>"date",
-class=>"comments",
-size=>"10",
-maxlength=>"10",
-readonly=>"$readonly_true",
-style=>"$readonly_style",
-default=>"");
} else {
my $today = &CalcDay($Now);
$today =~ s/-(\d)-/-0$1-/g;
$today =~ s/-(\d)$/-0$1/g;
$submit_button = $q->submit(-name=>"Submit",-value=>T("Submit"));
$title_field = $q->textfield(-name=>"title",
-class=>"comments",
-size=>"50",
-maxlength=>"100",
-default=>"");
$date_field = $q->textfield(-name=>"date",
-class=>"comments",
-size=>"10",
-maxlength=>"10",
-default=>"$today");
}
$txt =
$q->startform(-name=>"newpost",-method=>"POST",-action=>"$ScriptName") .
&GetHiddenValue("action","blog_newpost") .
&GetHiddenValue("id","$id") .
&GetHiddenValue("pageid","$pageid") .
T('Title will be converted into [[/Title]] automatically.')."<BR>".
T('Title:')." ".
$title_field." ".
T('Date').": ".
$date_field." ".
$submit_button.
$q->endform;
return $txt;
}
1;
3.2. macros/blog_calendar.pl 추가
sub blog_calendar {
my ($txt) = @_;
$txt =~ s/\&__LT__;blog_calendar\(([^,\n]+),([-+]?\d+),([-+]?\d+)\)\&__GT__;/&MacroBlogCalendar($1, $2, $3)/gei;
return $txt;
}
sub MacroBlogCalendar {
use Time::Local;
use strict;
my ($tocpage, $cal_year, $cal_month) = @_;
my $result='';
my $cal_result='';
my $cal_page;
my @cal_color = ("red", "black", "black", "black", "black", "black", "blue", "green");
my @cal_dow = (T('Su'), T('Mo'), T('Tu'), T('We'), T('Th'), T('Fr'), T('Sa'));
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Now+$TimeZoneOffset);
my ($this_year, $this_month, $this_day) = ($year, $mon, $mday);
my $cal_time;
my ($td_class, $span_style);
my $temp;
if (!($cal_month =~ /[-+]/) && ($cal_month > 12)) {
return "<calendar($tocpage,$cal_year,$cal_month)>";
}
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
my $tocitems = join("\n", @tocitem_List);
$cal_year = $this_year+1900 if ($cal_year == 0);
$cal_month = $this_month+1 if ($cal_month == 0);
if ($cal_year =~ /\+(\d+)/ ) {
$cal_year = $this_year+1900 + $1;
} elsif ($cal_year =~ /-(\d+)/ ) {
$cal_year = $this_year+1900 - $1;
}
if ($cal_month =~ /\+(\d+)/ ) {
$cal_month = $this_month+1 + $1;
while ($cal_month > 12) {
$cal_month -= 12;
$cal_year++;
}
} elsif ($cal_month =~ /-(\d+)/ ) {
$cal_month = $this_month+1 - $1;
while ($cal_month < 1) {
$cal_month += 12;
$cal_year--;
}
}
$cal_year = 2037 if ($cal_year > 2037);
$cal_year = 1902 if ($cal_year < 1902);
if ($cal_month < 10) {
$cal_month = "0" . $cal_month;
}
$result .= "<TABLE class='calendar'>";
$result .= "<CAPTION class='calendar'>"
."<a href=\"$ScriptName?$toc_mainpage/$cal_year-$cal_month\">"
.(length($toc_mainpage)?"$toc_mainpage<br>":"")
."$cal_year-$cal_month"
."</a>"
."</CAPTION>";
$result .= "<TR class='calendar'>";
for (0..6) {
$result .= "<TH class='calendar'>"
. "<span style='color:$cal_color[$_]'>$cal_dow[$_]</span></TH>";
}
$result .= "</TR>";
$cal_time = timelocal(0,0,0,1,$cal_month-1,$cal_year);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time);
$cal_time -= $wday * (60 * 60 * 24);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time);
my ($temp_month, $temp_day);
for (1..6) {
$result .= "<TR class='calendar'>";
for (0..6) {
($temp_month, $temp_day) = ($mon + 1, $mday);
$temp_month = "0".$temp_month if ($temp_month < 10);
$temp_day = "0".$temp_day if ($temp_day < 10);
$cal_page = ($year + 1900)."-".($temp_month)."-".($temp_day);
$cal_result = $mday;
$span_style = "";
if (($year == $this_year) && ($mon == $this_month) && ($mday == $this_day)) {
$td_class = "calendartoday";
$span_style = "text-decoration: underline; ";
} else {
$td_class = "calendar";
}
my ($page, $pagename) = ("", "");
if ($tocitems =~ /^\[\[(.+?)(\|.*)?\]\] $cal_page$/m) {
($page, $pagename) = ($1, $1);
$page =~ s|^/|$toc_mainpage/|;
$page = &FreeToNormal($page);
$span_style .= "font-weight: bold; text-decoration: underline; ";
$wday = 7;
if ($page eq $OpenPageName) {
$td_class .= "thispage";
}
}
if ($cal_month != ($mon+1)) {
$span_style .= "font-size: 0.9em; ";
}
$result .= "<td class='$td_class'>"
.(($page)?"<a href=\"$ScriptName?$page\" title=\"$pagename\">":"")
."<span style='color:$cal_color[$wday]; $span_style'>"
.$cal_result
."</span>"
.(($page)?"</a>":"")
."</td>";
$cal_time += (60 * 60 * 24);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($cal_time);
}
$result .= "</TR>";
last if (($mon+1 > $cal_month) || ($year+1900 > $cal_year));
}
$result .= "</table>";
return $result;
}
1;
3.3. macros/blog_includeorder.pl 추가
sub blog_includeorder {
my ($txt) = @_;
$txt =~ s/(^|\n)<blog_includeorder\(([^,]+),([-+]?\d+),([-+]?\d+)\)>([\r\f]*\n)/$1.&MacroBlogIncludeOrder($2,$3,$4).$5/geim;
return $txt;
}
sub MacroBlogIncludeOrder {
use strict;
my ($tocpage, $start, $end) = @_;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
($status, @tocitem_List) = &BlogGetListOrder($start, $end, @tocitem_List);
if (!$status) {
return "@tocitem_List";
}
my $txt;
my ($page, $date);
foreach my $item (@tocitem_List) {
if ($item =~ /^(.+)$FS1(.*)$FS1(.+)$/) {
($page, $date) = ($1, $3);
}
$page =~ s|^/|$toc_mainpage/|;
$page = &FreeToNormal($page);
$txt .= &MacroInclude($page);
}
return $txt;
}
1;
3.4. macros/blog_includeperiod.pl 추가
sub blog_includeperiod {
my ($txt) = @_;
$txt =~ s/(^|\n)<blog_includeperiod\(([^,]+),([\d-]+),([\d-]+)\)>([\r\f]*\n)/$1.&MacroBlogIncludePeriod($2,$3,$4).$5/geim;
return $txt;
}
sub MacroBlogIncludePeriod {
use strict;
my ($tocpage, $startdate, $enddate) = @_;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
($status, @tocitem_List) = &BlogGetListPeriod($startdate, $enddate, @tocitem_List);
if (!$status) {
return "@tocitem_List";
}
my $txt;
my ($page, $date);
foreach my $item (@tocitem_List) {
if ($item =~ /^(.+)$FS1(.*)$FS1(.+)$/) {
($page, $date) = ($1, $3);
}
$page =~ s|^/|$toc_mainpage/|;
$page = &FreeToNormal($page);
$txt .= &MacroInclude($page);
}
return $txt;
}
1;
3.5. macros/blog_listorder.pl 추가
sub blog_listorder {
my ($txt) = @_;
$txt =~ s/\&__LT__;blog_listorder\(([^,]+),([-+]?\d+),([-+]?\d+)(,([-+]?\d))?\)\&__GT__;/&MacroBlogListOrder($1,$2,$3,$5)/gei;
return $txt;
}
sub MacroBlogListOrder {
use strict;
my ($tocpage, $start, $end, $showdate) = @_;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
($status, @tocitem_List) = &BlogGetListOrder($start, $end, @tocitem_List);
if (!$status) {
return "@tocitem_List";
}
my $txt;
$txt = "<UL>";
my ($page, $pagename, $date, $pageid);
foreach my $item (@tocitem_List) {
if ($item =~ /^(.+)$FS1(.*)$FS1(.+)$/) {
($page, $pagename, $date) = ($1, $2, $3);
}
$pageid = $page;
$pageid =~ s|^/|$toc_mainpage/|;
$pageid = &FreeToNormal($pageid);
$page = $pagename if ($pagename);
if ($showdate == 0) {
$txt .= "<LI>".&GetPageOrEditLink($pageid,$page);
} elsif ($showdate < 0) {
$txt .= "<LI>($date) ".&GetPageOrEditLink($pageid,$page);
} else {
$txt .= "<LI>".&GetPageOrEditLink($pageid,$page)." ($date)";
}
}
$txt .= "</UL>";
return $txt;
}
1;
3.6. macros/blog_listperiod.pl 추가
sub blog_listperiod {
my ($txt) = @_;
$txt =~ s/\&__LT__;blog_listperiod\(([^,]+),([\d-]+),([\d-]+)(,([-+]?\d))?\)\&__GT__;/&MacroBlogListPeriod($1,$2,$3,$5)/gei;
return $txt;
}
sub MacroBlogListPeriod {
use strict;
my ($tocpage, $startdate, $enddate, $showdate) = @_;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
($status, @tocitem_List) = &BlogGetListPeriod($startdate, $enddate, @tocitem_List);
if (!$status) {
return "@tocitem_List";
}
my $txt;
$txt = "<UL>";
my ($page, $pagename, $date, $pageid);
foreach my $item (@tocitem_List) {
if ($item =~ /^(.+)$FS1(.*)$FS1(.+)$/) {
($page, $pagename, $date) = ($1, $2, $3);
}
$pageid = $page;
$pageid =~ s|^/|$toc_mainpage/|;
$pageid = &FreeToNormal($pageid);
$page = $pagename if ($pagename);
if ($showdate == 0) {
$txt .= "<LI>".&GetPageOrEditLink($pageid,$page);
} elsif ($showdate < 0) {
$txt .= "<LI>($date) ".&GetPageOrEditLink($pageid,$page);
} else {
$txt .= "<LI>".&GetPageOrEditLink($pageid,$page)." ($date)";
}
}
$txt .= "</UL>";
return $txt;
}
1;
3.7. macros/blog_prevnext.pl 추가
sub blog_prevnext {
my ($txt) = @_;
$txt =~ s/&__LT__;blog_prevnext\((.*?)\)&__GT__;/&MacroBlogPrevNext($1)/gei;
return $txt;
}
sub MacroBlogPrevNext {
use strict;
my ($tocpage) = @_;
my ($mainpage, $subpage);
my $txt;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "<font color='red'>blog_library.pl not found</font>";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "$toc_mainpage";
}
if ($OpenPageName =~ m|(.*)/(.*)|) {
($mainpage, $subpage) = ($1,$2);
} else {
$mainpage = $OpenPageName;
}
my $idx = 0;
for ($idx = 0; $idx <= $#tocitem_List; $idx++) {
my $line = $tocitem_List[$idx];
if ($line =~ m/\[\[$FreeLinkPattern(\|[^\]]+)?\]\]/) {
my $link = $1;
$link =~ s/ /_/g;
if (($link eq $OpenPageName) || ($link eq "/$subpage")) {
last;
}
} elsif ($line =~ m/$LinkPattern/) {
my $link = $1;
$link =~ s/ /_/g;
if (($link eq $OpenPageName) || ($link eq "/$subpage")) {
last;
}
}
}
my ($prev, $next);
if ($idx > $#tocitem_List) {
return "";
}
my $item;
my ($thispage, $thispagename, $thisdate);
$item = $tocitem_List[$idx];
if ($item =~ /\[\[(.+?)(\|.*)?\]\] (\d+-\d+-\d+)/) {
($thispage, $thispagename, $thisdate) = ($1, $1, $3);
$thispage =~ s|^/|$toc_mainpage/|;
$thispage = &FreeToNormal($thispage);
}
my ($prevpage, $prevpagename, $prevdate);
my ($nextpage, $nextpagename, $nextdate);
if ($idx > 0) {
$item = $tocitem_List[$idx-1];
if ($item =~ /\[\[(.+?)(\|.*)?\]\] (\d+-\d+-\d+)/) {
($prevpage, $prevpagename, $prevdate) = ($1, $1, $3);
$prevpage =~ s|^/|$toc_mainpage/|;
$prevpage = &FreeToNormal($prevpage);
}
}
if ($idx < $#tocitem_List) {
$item = $tocitem_List[$idx+1];
if ($item =~ /\[\[(.+?)(\|.*)?\]\] (\d+-\d+-\d+)/) {
($nextpage, $nextpagename, $nextdate) = ($1, $1, $3);
$nextpage =~ s|^/|$toc_mainpage/|;
$nextpage = &FreeToNormal($nextpage);
}
}
my $shortCutUrl = "$ScriptName".&ScriptLinkChar();
my $shortCutKey;
$txt = "<CENTER>";
if ($prevpage) {
$txt .= "<b><<</b> ".
&GetPageOrEditLink($prevpage, $prevpagename).
" ($prevdate)[p]";
$shortCutKey .= "key['p'] = \"${shortCutUrl}$prevpage\";\n"
}
$txt .= "  <b>|</b> $thispagename ($thisdate) <b>|</b> ";
if ($nextpage) {
$txt .= &GetPageOrEditLink($nextpage, $nextpagename).
" ($nextdate)[n]".
" <b>>></b>";
$shortCutKey .= "key['n'] = \"${shortCutUrl}$nextpage\";\n"
}
$txt .= "</CENTER>\n";
if ($UseShortcut && $shortCutKey) {
$txt .= "<script>\n".
"<!--\n".
$shortCutKey.
"-->\n".
"</script>";
}
return $txt;
}
1;
3.8. macors/blog_prevnextmonth.pl 추가
sub blog_prevnextmonth {
my ($txt) = @_;
$txt =~ s/&__LT__;blog_prevnextmonth&__GT__;/&MacroBlogPrevNextMonth()/gei;
return $txt;
}
sub MacroBlogPrevNextMonth {
use strict;
if ($OpenPageName =~ m|^(.*/)?(\d{4})-(\d{2})$|) {
my ($mainpage, $year, $month) = ($1, $2, $3);
my ($prev_year, $prev_month) = ($year, $month - 1);
my ($next_year, $next_month) = ($year, $month + 1);
if ($prev_month <= 0) {
$prev_year--;
$prev_month = 12;
} elsif ($next_month >= 13) {
$next_year++;
$next_month = 1;
}
if ($prev_month < 10) {
$prev_month = "0" . $prev_month;
}
if ($next_month < 10) {
$next_month = "0" . $next_month;
}
my $prev_page = "$mainpage$prev_year-$prev_month";
my $next_page = "$mainpage$next_year-$next_month";
my $shortCutUrl = "$ScriptName".&ScriptLinkChar();
my $txt;
$txt = "<CENTER>".
"<b><<<</b> ".
&GetPageOrEditLink($next_page).
" [p]".
"  <b>|</b> ".T('Monthly View')." <b>|</b> ".
&GetPageOrEditLink($prev_page).
" [n]".
" <b>>>></b>".
"</CENTER>";
$txt .= <<EOF;
<script>
<!--
key['p'] = "${shortCutUrl}$next_page";
key['n'] = "${shortCutUrl}$prev_page";
-->
</script>
EOF
return $txt;
} else {
return "";
}
}
1;
3.9. macros/blog_library.pl 추가
sub BlogReadToc($tocpage) {
use strict;
my ($tocpage) = @_;
$tocpage = &FreeToNormal(&RemoveLink($tocpage));
if (my $temp = &ValidId($tocpage)) {
return (0, "<font color='red'>$temp</font>");
}
my ($toc_mainpage, $toc_subpage);
if ($tocpage =~ m|(.*)/(.*)|) {
($toc_mainpage, $toc_subpage) = ($1,$2);
} else {
$toc_mainpage = $tocpage;
}
my ($fname, $status, $data);
$fname = &GetPageFile($tocpage);
if (!(-f $fname)) {
return (0, "<font color='red'>No such page: $tocpage</font>");
}
($status, $data) = &ReadFile($fname);
if (!$status) {
return (0, "<font color='red'>Error in read pagefile: $tocpage</font>");
}
my %temp_Page = split(/$FS1/, $data, -1);
my %temp_Section = split(/$FS2/, $temp_Page{'text_default'}, -1);
my %temp_Text = split(/$FS3/, $temp_Section{'data'}, -1);
my $tocpage_Text = $temp_Text{'text'};
my @tocpage_Lines = split('\n',$tocpage_Text);
my @tocitem_List;
foreach my $line (@tocpage_Lines) {
if ($line =~ m/^* (\[\[.+?\]\] \d+-\d+-\d+)\s*$/) {
push(@tocitem_List, $1);
}
}
return (1, $toc_mainpage, @tocitem_List);
}
sub BlogGetListOrder {
use strict;
my ($start, $end, @tocitem_List) = @_;
if (($start == 0) || ($end == 0)) {
return (0, "<font color='red'>Invalid parameter: 0</font>");
}
if ($start > 0) {
$start--;
} else {
$start = $#tocitem_List + $start + 1;
}
if ($end > 0) {
$end--;
} else {
$end = $#tocitem_List + $end + 1;
}
$start = 0 if ($start < 0);
$start = $#tocitem_List if ($start > $#tocitem_List);
$end = 0 if ($end < 0);
$end = $#tocitem_List if ($end > $#tocitem_List);
if ($start <= $end) {
@tocitem_List = @tocitem_List[$start .. $end];
} else {
@tocitem_List = reverse(@tocitem_List[$end .. $start]);
}
my @list;
my ($page, $pagename, $date);
foreach my $item (@tocitem_List) {
if ($item =~ /\[\[(.+?)(\|.*)?\]\] (\d+)-(\d+)-(\d+)/) {
$page = $1;
$pagename = $2;
$date = sprintf("%4d-%02d-%02d",$3,$4,$5);
$pagename =~ s/^\|//;
push(@list, "$page$FS1$pagename$FS1$date");
}
}
return ("1", @list);
}
sub BlogGetListPeriod {
use strict;
my ($startdate, $enddate, @tocitem_List) = @_;
if ($startdate =~ /^(\d{4})-(\d{1,2})-(\d{1,2})$/) {
$startdate = sprintf("%4d%02d%02d",$1,$2,$3);
} else {
return (0,"<font color='red'>Invalid parameter: $startdate</font>");
}
if ($enddate =~ /^(\d+)-(\d+)-(\d+)$/) {
$enddate = sprintf("%4d%02d%02d",$1,$2,$3);
} else {
return (0,"<font color='red'>Invalid parameter: $enddate</font>");
}
my @list;
my ($page, $pagename, $date, $reverse);
if ($startdate > $enddate) {
($startdate, $enddate, $reverse) = ($enddate, $startdate, 1);
}
foreach my $item (@tocitem_List) {
if ($item =~ /\[\[(.+?)(\|.*)?\]\] (\d+)-(\d+)-(\d+)/) {
$page = $1;
$pagename = $2;
$date = sprintf("%4d%02d%02d",$3,$4,$5);
last if ($date < $startdate);
if ($date <= $enddate) {
$date = sprintf("%4d-%02d-%02d",$3,$4,$5);
$pagename =~ s/^\|//;
push(@list, "$page$FS1$pagename$FS1$date");
}
}
}
@list = reverse @list if ($reverse);
return (1, @list);
}
1;
3.10. action/blog_newpost.pl 추가
sub action_blog_newpost {
use strict;
my $id = &GetParam("id","");
my $pageid = &GetParam("pageid","");
my $title = &GetParam("title","");
my $date = &GetParam("date","");
$title =~ s/^\s*//g;
$title =~ s/\s*$//g;
$title = "[[/$title]]";
if ($date =~ /^(\d+)-(\d+)-(\d+)$/) {
$date = sprintf("%4d-%02d-%02d",$1,$2,$3);
}
&OpenPage($id);
&OpenDefaultText();
my $string = $Text{'text'};
$string =~ s/(<blog_newpost\($id\)>)/$1\n* $title $date/;
if (!&UserCanEdit($id,1)) {
$pageid = "";
}
&DoPostMain($string, $id, "*", $Section{'ts'}, 0, 1, $pageid);
return;
}
1;
3.11. action/comments.pl 수정
"블로그 지원을 위한 꽁수"라고 적은 단락을 추가
sub action_comments {
use strict;
my $id = &GetParam("id", "");
my $pageid = &GetParam("pageid", "");
my $name = &GetParam("name", "");
my $newcomments = &GetParam("comment", "");
my $up = &GetParam("up", "");
my ($timestamp) = CalcDay($Now) . " " . CalcTime($Now);
my $string;
my $long = &GetParam("long", "");
&ValidIdOrDie($id);
my ($blogrcpage, $blogrccomment);
if ($id =~ m/(.+)(\/|%2f|%2F)(.+)/) {
$blogrcpage = "$1/BlogRc";
} else {
$blogrcpage = "BlogRc";
}
if (-f &GetPageFile($blogrcpage)) {
$blogrccomment = $newcomments;
} else {
$blogrcpage = "";
}
my $threadindent = &GetParam("threadindent", "");
my $abs_up = abs($up);
my ($threshold1, $threshold2) = (100000000, 1000000000);
if ($newcomments =~ /^\s*$/) {
&ReBrowsePage($pageid, "", 0);
return;
}
$name = &GetRemoteHost(0) if ($name eq "");
$name =~ s/,/./g;
$newcomments = &QuoteHtml($newcomments);
&OpenPage($id);
&OpenDefaultText();
$string = $Text{'text'};
if ($threadindent ne '') {
$newcomments =~ s/^\s*//g;
$newcomments =~ s/\s*$//g;
$newcomments =~ s/(\n)\s*(\r?\n)/$1$2/g;
$newcomments =~ s/(\r?\n)/ \\\\$1/g;
my ($comment_head, $comment_tail) = ("", "");
my $newup;
if (($abs_up >= 100) && ($abs_up <= $threshold2)) {
$newup = $Now - $threshold2;
} else {
$newup = $Now;
}
$comment_tail = "<thread($id,$newup," . ($threadindent+1) . ")>";
if ($threadindent >= 1) {
for (1 .. $threadindent) {
$comment_head .= ":";
}
$comment_head .= " ";
} else {
}
if (($up > 0) && ($up < $threshold1)) {
$string =~ s/(\<thread\($id,$up(,\d+)?\)\>)/$comment_head$newcomments <mysign($name,$timestamp)>\n$comment_tail\n\n$1/;
} else {
$string =~ s/(\<thread\($id,$up(,\d+)?\)\>)/$1\n\n$comment_head$newcomments <mysign($name,$timestamp)>\n$comment_tail/;
}
} elsif ($long) {
$newcomments =~ s/^\s*//g;
$newcomments =~ s/\s*$//g;
$newcomments =~ s/(\n)\s*(\r?\n)/$1$2/g;
$newcomments =~ s/(\r?\n)/ \\\\$1/g;
if ($up > 0) {
$string =~ s/(\<longcomments\($id,$up\)\>)/\n$newcomments <mysign($name,$timestamp)>\n$1/;
} else {
$string =~ s/(\<longcomments\($id,$up\)\>)/$1\n$newcomments <mysign($name,$timestamp)>\n/;
}
} else {
$newcomments =~ s/(----+)/<nowiki>$1<\/nowiki>/g;
if ($up > 0) {
$string =~ s/\<comments\($id,$up\)\>/* ''' $name ''' : $newcomments - <small>$timestamp<\/small>\n\<comments\($id,$up\)\>/;
} else {
$string =~ s/\<comments\($id,$up\)\>/\<comments\($id,$up\)\>\n* ''' $name ''' : $newcomments - <small>$timestamp<\/small>/;
}
}
if (((!&UserCanEdit($id,1)) && (($abs_up < 100) || ($abs_up > $threshold2))) || (&UserIsBanned())) {
$pageid = "";
}
if ($pageid && $blogrcpage) {
$blogrccomment =~ s/(\r?\n)/ /g;
$blogrccomment =~ s/\[/{/g;
$blogrccomment =~ s/\]/}/g;
if (length($blogrccomment) > 30) {
$blogrccomment = substr($blogrccomment, 0, 27);
$blogrccomment =~ s/(([\x80-\xff].)*)[\x80-\xff]?$/$1/;
$blogrccomment .= "...";
}
$blogrccomment = &QuoteHtml($blogrccomment);
$blogrccomment =~ s/----+/---/g;
$blogrccomment =~ s/^ *//;
$blogrccomment = "C) $blogrccomment";
my ($fname, $status, $data);
$fname = &GetPageFile($blogrcpage);
if (-f $fname) {
($status, $data) = &ReadFile($fname);
if ($status) {
my %temp_Page = split(/$FS1/, $data, -1);
my %temp_Section = split(/$FS2/, $temp_Page{'text_default'}, -1);
my %temp_Text = split(/$FS3/, $temp_Section{'data'}, -1);
my $blogrc_Text = $temp_Text{'text'};
my $date = &CalcDayNow();
if ($date =~ /(\d+)-(\d+)-(\d+)/) {
$date = sprintf("%4d-%02d-%02d",$1,$2,$3);
}
if ($blogrc_Text =~ /^\*/m) {
$blogrc_Text =~ s/^\*/* [[$id|$blogrccomment]] $date\n*/m;
} else {
$blogrc_Text .= "\n* [[$id|$blogrccomment]] $date";
}
my $backup = $Section{'ts'};
&DoPostMain($blogrc_Text, $blogrcpage, "", $temp_Section{'ts'}, 0, 1, "!!");
$Section{'ts'} = $backup;
}
}
}
DoPostMain($string, $id, "*", $Section{'ts'}, 0, 0, $pageid);
return;
}
1;
3.12. action/trackback.pl 수정
"블로그 지원을 위한 꽁수"라고 적은 단락을 추가
sub action_trackback {
use strict;
my $id = &GetParam("id","");
my $normal_id = $id;
my $url = &GetParam('url');
my $title = &GetParam('title', $url);
my $blog_name = &GetParam('blog_name');
my $excerpt = &GetParam('excerpt');
my ($blogrcpage, $blogrccomment);
if ($id =~ m/(.+)(\/|%2f|%2F)(.+)/) {
$blogrcpage = "$1/BlogRc";
} else {
$blogrcpage = "BlogRc";
}
if (-f &GetPageFile($blogrcpage)) {
$blogrccomment = $excerpt;
} else {
$blogrcpage = "";
}
if (length($excerpt) > 255) {
$excerpt = substr($excerpt, 0, 252);
$excerpt =~ s/(([\x80-\xff].)*)[\x80-\xff]?$/$1/;
$excerpt .= "...";
}
$excerpt =~ s/(\r?\n)/ /g;
$excerpt = &QuoteHtml($excerpt);
$excerpt = "<nowiki>$excerpt</nowiki>";
if ($FreeLinks) {
$normal_id = &FreeToNormal($id);
}
if ($url eq '') {
&SendTrackbackResponse("1", "No URL (url)");
} elsif ($id eq '') {
&SendTrackbackResponse("1", "No Pagename (id)");
} elsif (!&PageCanReceiveTrackbackPing($normal_id)) {
&SendTrackbackResponse("1", "Invalid Pagename (Page is missing, or Trackback is not allowed)");
} elsif (my $bannedText = &TextIsBanned($blog_name.$url.$title.$excerpt)) {
&SendTrackbackResponse("1", "[$bannedText] is a Banned text");
} else {
&OpenPage($normal_id);
&OpenDefaultText();
my $string = $Text{'text'};
my $macro = "\<trackbackreceived\>";
if (!($string =~ /$macro/)) {
$string .= "\n$macro\n";
}
my $timestamp = &CalcDay($Now) . " " . &CalcTime($Now);
my $newtrackbackreceived = "* " .
&Ts('Trackback from %s', "'''<nowiki>$blog_name</nowiki>'''") .
" $timestamp\n" .
"** " . &T('Title:') . " [$url $title]\n" .
"** " . &T('Content:') . " $excerpt";
$string =~ s/($macro)/$newtrackbackreceived\n$1/;
if ($blogrcpage) {
$blogrccomment =~ s/(\r?\n)/ /g;
$blogrccomment =~ s/\[/{/g;
$blogrccomment =~ s/\]/}/g;
if (length($blogrccomment) > 30) {
$blogrccomment = substr($blogrccomment, 0, 27);
$blogrccomment =~ s/(([\x80-\xff].)*)[\x80-\xff]?$/$1/;
$blogrccomment .= "...";
}
$blogrccomment = &QuoteHtml($blogrccomment);
$blogrccomment =~ s/----+/---/g;
$blogrccomment =~ s/^ *//;
$blogrccomment = "T) $blogrccomment";
my ($fname, $status, $data);
$fname = &GetPageFile($blogrcpage);
if (-f $fname) {
($status, $data) = &ReadFile($fname);
if ($status) {
my %temp_Page = split(/$FS1/, $data, -1);
my %temp_Section = split(/$FS2/, $temp_Page{'text_default'}, -1);
my %temp_Text = split(/$FS3/, $temp_Section{'data'}, -1);
my $blogrc_Text = $temp_Text{'text'};
my $date = &CalcDayNow();
if ($date =~ /(\d+)-(\d+)-(\d+)/) {
$date = sprintf("%4d-%02d-%02d",$1,$2,$3);
}
if ($blogrc_Text =~ /^\*/m) {
$blogrc_Text =~ s/^\*/* [[$id|$blogrccomment]] $date\n*/m;
} else {
$blogrc_Text .= "\n* [[$id|$blogrccomment]] $date";
}
my $backup = $Section{'ts'};
&DoPostMain($blogrc_Text, $blogrcpage, "", $temp_Section{'ts'}, 0, 1, "!!");
$Section{'ts'} = $backup;
}
}
}
&DoPostMain($string, $id, &T('New Trackback Received'), $Section{'ts'}, 0, 0, "!!");
&SendTrackbackResponse(0, "");
}
}
sub SendTrackbackResponse {
my ($code, $message) = @_;
if ($code == 0) {
print <<END;
Content-Type: application/xml; charset: iso-8859-1\n
<?xml version="1.0" encoding="iso-8859-1"?>
<response>
<error>0</error>
</response>
END
} else {
print <<END;
Content-Type: application/xml; charset: iso-8859-1\n
<?xml version="1.0" encoding="iso-8859-1"?>
<response>
<error>$code</error>
<message>$message</message>
</response>
END
}
}
1;
3.13. macros/blog_rss.pl 추가
sub blog_rss {
my ($txt) = @_;
$txt =~ s/\&__LT__;blog_rss\((.*?)\)&__GT__;/&MacroBlogRss($1)/gei;
$txt =~ s/&__LT__;blog_rss&__GT__;.*?&__LT__;\/blog_rss&__GT__;//geis;
return $txt;
}
sub MacroBlogRss {
use strict;
my ($arg) = @_;
my $txt;
my ($listpage, $blogpage);
if ($arg =~ /^([^,]+)(,([^,]+))?$/) {
($listpage, $blogpage) = ($1, $3);
} else {
return "<font color='red'>Invalid args</font>";
}
my $blogname;
$listpage = &RemoveLink($listpage);
$blogname = $listpage;
$listpage = &FreeToNormal($listpage);
$blogpage = &RemoveLink($blogpage);
$blogname = $blogpage if ($blogpage);
$blogpage = &FreeToNormal($blogpage);
$txt = &ScriptLink("action=blog_rss&listpage=$listpage&blogpage=$blogpage",
"<img align='absmiddle' src='$IconDir/xml_rss.gif'> Get RSS of $blogname");
return $txt;
}
1;
3.14. action/blog_rss.pl 추가
my @ChannelField = ('title','link','description','language',
'copyright','manageingEditor','webMaster','pubDate',
'lastBuildDate','category','generator','docs','could',
'ttl','image','rating','textInput','skipHours','skipDays');
my @ItemField = ('title','link','description','author','category',
'comments','enclosure','guid','pubDate','source');
my %NeedCdata = map { $_ => 1 } ('description');
my (%RssChannelField, %RssItemFieldInList, %RssItemField, $ListPageAuthor);
sub action_blog_rss {
use strict;
my $listpage = &GetParam("listpage","");
my $blogpage = &GetParam("blogpage","");
my $num_items = &GetParam("items",15);
my $xml = "";
my $cachefile = $listpage."__".$blogpage."__".$num_items;
$cachefile =~ s/(\W)/uc sprintf "_%02x", ord($1)/eg;
$cachefile = "$TempDir/rss_$cachefile.xml";
if (-f $cachefile) {
my $cache_mtime = (stat($cachefile))[9];
my $rclog_mtime = (stat($RcFile))[9];
if ($cache_mtime > $rclog_mtime) {
my ($status, $data) = &ReadFile($cachefile);
if ($status) {
$xml = $data;
}
}
}
if ($xml eq "") {
my ($rssHeader, $rssBody, $rssFooter);
$RssChannelField{'title'} = &QuoteHtml($SiteName);
$FullUrl = $q->url(-full=>1) if ($FullUrl eq "");
$QuotedFullUrl = &QuoteHtml($FullUrl);
$RssChannelField{'link'} = $QuotedFullUrl;
$RssChannelField{'link'} .= &ScriptLinkChar() . $blogpage if ($blogpage);
$RssChannelField{'description'} = $SiteDescription;
$RssChannelField{'language'} = "ko";
$RssChannelField{'pubDate'} = &BlogRssGetPubDate($Now);
&OpenPage($listpage);
&OpenDefaultText;
$ListPageAuthor = $Section{'username'};
&BlogRssGetUserDefinedValue($Text{'text'}, "list");
$rssHeader = <<EOF;
<?xml version="1.0" encoding="$HttpCharset" ?>
<rss version="2.0">
<channel>
EOF
foreach my $field (@ChannelField) {
if ($RssChannelField{$field} ne "") {
$rssHeader .=
"<$field>".
(($NeedCdata{$field})?("<![CDATA[".$RssChannelField{$field}."]]>"):($RssChannelField{$field})).
"</$field>".
"\n";
}
}
$rssFooter = <<EOF;
</channel>
</rss>
EOF
$rssBody = &BlogRssGetItems($listpage, $num_items);
$xml = $rssHeader.
$rssBody.
$rssFooter;
&WriteStringToFile($cachefile, $xml);
}
print "Content-type: text/xml\n\n";
print $xml;
return;
}
sub BlogRssGetItems {
use strict;
my ($tocpage, $num_items) = @_;
my ($MacrosDir, $MyMacrosDir) = ("./macros/", "./mymacros/");
if (-f "$MyMacrosDir/blog_library.pl") {
require "./$MyMacrosDir/blog_library.pl";
} elsif (-f "$MacrosDir/blog_library.pl") {
require "./$MacrosDir/blog_library.pl";
} else {
return "";
}
my ($status, $toc_mainpage, @tocitem_List) = &BlogReadToc($tocpage);
if (!$status) {
return "";
}
($status, @tocitem_List) = &BlogGetListOrder(1, $num_items, @tocitem_List);
if (!$status) {
return "";
}
my $txt;
my ($page, $pagename, $date, $pageid);
foreach my $item (@tocitem_List) {
if ($item =~ /^(.+)$FS1(.*)$FS1(.+)$/) {
($page, $pagename, $date) = ($1, $2, $3);
}
$pageid = $page;
$pageid =~ s|^/|$toc_mainpage/|;
$pageid = &FreeToNormal($pageid);
next if (not -f &GetPageFile($pageid));
%RssItemField = %RssItemFieldInList;
&OpenPage($pageid);
&OpenDefaultText();
$RssItemField{'title'} = $page;
$RssItemField{'link'} = $QuotedFullUrl.&ScriptLinkChar().&EncodeUrl($pageid);
my $description = $Text{'text'};
$description =~ s/<noinclude>.*?<\/noinclude>//igs;
$description =~ s/<blog_rss>.*?<\/blog_rss>//igs;
$description =~ s/\n/<br \/>\n/g;
$RssItemField{'description'} = $description;
if (not $RssItemField{'author'}) {
$RssItemField{'author'} = $ListPageAuthor;
}
$RssItemField{'pubDate'} = &BlogRssGetPubDate($Page{'tscreate'});
&BlogRssGetUserDefinedValue($Text{'text'});
$txt .= "<item>\n";
foreach my $field (@ItemField) {
if ($RssItemField{$field} ne "") {
$txt .=
"<$field>".
(($NeedCdata{$field})?"<![CDATA[".$RssItemField{$field}."]]>":$RssItemField{$field}).
"</$field>".
"\n";
}
}
$txt .= "</item>\n";
}
return $txt;
}
sub BlogRssGetPubDate {
my ($ts) = @_;
my @dow = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
my @month = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
my ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime($ts);
my $pubDate = sprintf("%3s, %02d %3s %04d %02d:%02d:%02d +%02d00",
$dow[$wday], $mday, $month[$mon], $year+1900, $hour, $min, $sec, $RssTimeZone);
return $pubDate;
}
sub BlogRssGetUserDefinedValue {
my ($text, $where) = @_;
my ($text_channel, $text_item);
my $text_blog;
while ($text =~ /<blog_rss>(.+?)<\/blog_rss>/igs) {
$text_blog .= $1;
}
while ($text_blog =~ /<channel>(.+?)<\/channel>/igs) {
$text_channel .= $1;
}
while ($text_channel =~ s/<item>(.+?)<\/item>//igs) {
$text_item .= $1;
}
while ($text_channel =~ /<(.+?)>(.+?)<\/\1>/gs) {
$RssChannelField{$1} = $2;
}
while ($text_item =~ /<(.+?)>(.+?)<\/\1>/gs) {
if ($where eq "list") {
$RssItemFieldInList{$1} = $2;
} else {
$RssItemField{$1} = $2;
}
}
}
1;
4. 추가 업데이트 내역
ext1.82a - 목차 페이지에 [[페이지이름|문자열]] 형식으로 쓰여진 것을 처리할 수 있게 함.
ext1.82c - blog_prevnextmonth 매크로 추가.
ext1.82d - /Comments매크로와 /TrackBack 코드를 고쳐서, 코멘트나 트랙백이 달릴 때 그 내역을 기록하게 함.
ext1.83 - blog_rss 매크로, blog_rss 액션 추가
ext1.83a - 사용자가 RSS출력을 제어할 수 있게 함.
ext1.90 - /매크로파라메터에이중대괄호허용함
ext2.1b - blog_includeperiod나 blog_listperiod에서, 시작날짜와 끝날짜를 거꾸로 주면 출력순서도 반대가 되게 함
ext2.1d - blog_includeperiod, blog_includeorder 매크로는 다른 include시리즈처럼 한 줄에 그 매크로만 있고 좌우에 다른 문자나 공백이 없을 때만 동작하게 함.
5. 사용자 의견
다음 두 가지에 대해 누가 좀 가르쳐 주세요.
1. 각 글의 description 항목에서, 태터와 이글루스를 보면
<item>
<title>글제목</title>
<link>글주소</link>
<description><![CDATA[ 글내용]]><description>
...
</item>
위와 같이 "<![CDATA[ "와 "]]>"로 내용을 묶던데 이게 무슨 의미인지요? 꼭 필요한 건가요? 다른 사이트를 보면 이게 없는 곳도 있고...
2. 1을 쓰는 동안 잊어버렸습니다 -_-;;
- 1은 CDATA가 없으면 글 내용에 HTML 태그가 들어가 있을 때 그걸 XML 엔트리(라고 하던가?)로 해석하게 되기 때문에 문제가 될 수 있습니다. 예를 들어 HTML에서는 줄바꿀 때 <br>만 해주면 되지만 이게 XML로 가면 닫는 태그가 없다고 에러가 나겠죠.
- 그렇군요. 그럼 사용해야겠네요.
description 뿐 아니라 title, link, pubDate 등 URL이나 날짜 항목도 CDATA로 묶어도 되는 걸까요? 지금 소스를 좀 고치고 있는데 일부 필드만 CDATA를 쓰고 일부 필드는 그렇지 않게 하려니 너무 지저분해지네요.
으음... 온갖 편법과 꽁수가 난무하고 소스도 무지 늘어났지만... 저자동고유연성의 극치를 달리는 블로그 기능이로군요. 한 위키 안에 여러 블로그를 두고 각각 RSS를 따로 제공할 수 있습니다. 그리고 모듈화 덕분에 wiki.pl도 거의 고치지 않고 되었으니 뭐... 이만하면 만족.
위키위키분류