구글 블로그 스팟 테마중 댓글 작성시간이 second ago 로 고정되는 경우 해결법

 구글 블로그 스팟의 테마는 상당히 많이 있어서 구조와 디자인이 무척 다양하다. 그 덕에 일부 특별한 디자인의 테마는 몇몇 기능과 위젯을 자체적으로 제작해서 넣게 되는데, 이 때문에 생각지도 못한 문제가 발생하기도 한다.

이번 포스팅은 그 일부 테마에서 댓글 작성 시간이 무조건 "second ago"로 나오는 현상을 해결한 내용이다.

구글 블로그 댓글 second ago 고정 해결

1. 적용 테마

이 문제가 있던 테마는 지난 포스팅에서 소개한 Jago Desain 에서 나온 블로그스팟 테마 시리즈 이다. 이 테마 시리즈가 궁금하면 여기를 클릭해 보자. 유료 테마이기는 한데 테마 이름으로 검색을 해보면 무료로 받을 수 있는 곳들이 나온다.

비단 여기 시리즈 테마 말고도 비슷한 기능의 테마라면 거의 동일하게 적용이 될 것이라 생각이 된다.


2. 문제가 되는 테마의 특징

  문제가 되는 테마는 댓글 작성시간이 블로그 스팟 설정에서 선택한 날자 표기 방식이 아닌, 작성일 기준으로 얼마나 지났는가를 표기하는 방식으로 구성이 된 테마이다.

즉 1일전, 1달전, 1년전 식으로 표기하는 디자인의 테마는 아마도 비슷하게 적용이 될것이다.


3. 테마의 이상현상

  필자가 수정하고 있는 블로그 테마는 댓글을 작성하면, 작성한 시간과 관계없이 무조건 "seconds ago" 라고 표기가 된다.


Second ago 오류
Second ago 오류


기본적으로 구글 블로그는 댓글의 표시부와 댓글 입력 상자가 하나의 모듈로 구성이 되어 있는것 같다.(몇 개의 테마를 분석해본 결과로, 필자가 잘못 알고있는 것일 수 도 있다) 그래서 거의 대부분의 테마는 동일한 형태의 댓글 목록과 입력상자를 제공한다.

그러나 이렇게 출력형태가 다른 경우는 독자적인 프로그램으로 화면 요소를 구성한 경우라 예상치 못한 오류가 생기기도 한다.


4. 테마 댓글부의 구조와 해결방법

  4.1. 테마 댓글부의 구조

   이런형태의 테마는 기본 댓글의 출력부에서 날짜에 관한 문자열을 받아, 문자열의 구조를 변형해서 숫자로 변환 후 현재 날짜와 비교해 현시간부로 얼마나 오래전에 댓글을 작성했는지 출력하는 함수를 만들어서 디자인에 적용하게 된다.

 

  4.2. 해결방법 첫번째, 댓글 타임스탬프 변경

  이런 함수로 날짜를 계산하면, 문제되는 부분이 하나가 있는데, 함수가 원하는 형식의 데이타가 들어와야 정상적인 기능을 한다는 것이다. 

그런데 블로그 설정 화면에 가보면 다양한 포멧의 시간 표시 방식을 지원한다. 때문에 우선 블로그 설정에서 테마가 원하는 형식의 댓글 타임 스템프를 선택해 준다.

블로그 관리화면 > 설정 > 댓글 타임스템프 형식 을 선택한다.


댓글 타임스탬프 형식 메뉴 위치
댓글 타임스탬프 형식 메뉴 위치


아래 이미지와 같은 형식의 타임스탬프를 선택해 주고 저장을 한다.

타임 스탬프 선택
타임 스탬프 선택

만약 이것만 바꾸고 정상 작동하면 성공, 정상작동을 안하면 위에서 부터 차례대로 다 적용해 봐야한다. 그리고 만약 위에 언급한 회사라면 이 형식이 맞다. 

타임스탬프 형식을 바꿔도 테마에 변화가 없다면 이제 직접적으로 테마 소스를 수정해야한다.


  4.3. 해결방법 두번째, 테마소스 직접 수정

자 여기까지 읽고 있다면 운이 없게도 소스 수정을 해야하는 분들일 것이다.

우선 테마에서 timeAgo를 검색해본다. 위에 언급한 테마라면 바로 나올것이고 그게 아니라면 여러 방법으로 검색해 봐야한다.

일단 찾았다면 아래와 같은 코드가 나올것이다.

<script>/*<![CDATA[*/ (function timeAgo(selector) { var templates = {prefix: "", suffix: "", seconds: "second ago", minute: "1 min", minutes: "%d min", hour: "1 hour", hours: "%d hour", day: "1 day", days: "%d days", month: "1 month", months: "%d month", year: "1 year", years: "%d years"}; var template = function(t, n) { return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n))); }; var timer = function(time) { if (!time) return; time = time.replace(/\.\d+/, ""); time = time.replace(/-/, "/").replace(/-/, "/"); time = time.replace(/T/, " ").replace(/Z/, " UTC"); time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); time = new Date(time * 1000 || time); var now = new Date(); var seconds = ((now.getTime() - time) * .001) >> 0; var minutes = seconds / 60; var hours = minutes / 60; var days = hours / 24; var years = days / 365; return templates.prefix + ( seconds < 45 && template('seconds', seconds) || seconds < 90 && template('minute', 1) || minutes < 45 && template('minutes', minutes) || minutes < 90 && template('hour', 1) || hours < 24 && template('hours', hours) || hours < 42 && template('day', 1) || days < 30 && template('days', days) || days < 45 && template('month', 1) || days < 365 && template('months', days / 30) || years < 1.5 && template('year', 1) || template('years', years) ) + templates.suffix; }; var elements = document.getElementsByClassName('dtTm'); for (var i in elements) { var $this = elements[i]; if (typeof $this === 'object') { $this.innerHTML = timer($this.getAttribute('title') || $this.getAttribute('data-datetime')); } } setTimeout(timeAgo, 60000); })(); /*]]>*/</script>


뭔가 스크립트가 이어져 있어 한눈에 안들어 오는데 정리를 한번 해보면 아래와 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<script>/*<![CDATA[*/ 
(
function timeAgo(selector) { 
var templates = {
    prefix: ""
    suffix: ""
    seconds: "second ago"
    minute: "1 min"
    minutes: "%d min"
    hour: "1 hour"
    hours: "%d hour"
    day: "1 day"
    days: "%d days"
    month: "1 month"
    months: "%d month"
    year: "1 year"
    years: "%d years"
}; 
var template = function(t, n) { 
    return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n))); 
}; 
var timer = function(time) { 
    if (!time) return
    time = time.replace(/\.\d+/""); 
    time = time.replace(/-/"/").replace(/-/"/"); 
    time = time.replace(/T/" ").replace(/Z/" UTC"); 
    time = time.replace(/([\+\-]\d\d)\:?(\d\d)/" $1$2"); 
    time = new Date(time * 1000 || time); 
var now = new Date(); 
var seconds = ((now.getTime() - time) * .001>> 0
var minutes = seconds / 60
var hours = minutes / 60
var days = hours / 24
var years = days / 365
return templates.prefix + ( seconds < 45 && template('seconds', seconds) || seconds < 90 && template('minute'1|| minutes < 45 && template('minutes', minutes) || minutes < 90 && template('hour'1|| hours < 24 && template('hours', hours) || hours < 42 && template('day'1|| days < 30 && template('days', days) || days < 45 && template('month'1|| days < 365 && template('months', days / 30|| years < 1.5 && template('year'1|| template('years', years) ) + templates.suffix; 
}; 
var elements = document.getElementsByClassName('dtTm'); 
for (var i in elements) { 
    var $this = elements[i];
    if (typeof $this === 'object'
    { $this.innerHTML = timer($this.getAttribute('title'|| $this.getAttribute('data-datetime')); } 
    } 
    setTimeout(timeAgo, 60000); 
    }
)(); /*]]>*/
</script>
cs


사실 필자는 자바스크립트를 할 줄 모른다. 그래서 아는만큼 설명을 하자면,

 timeAgo( ) 함수는 게시물의 게시일자를 현재날짜와 비교해서 얼만큼 전에 게시한 글인지 결과 문자열을 반환하는 함수이다.

4~18행은 표시할 문자의 변수를 선언한 부분으로 잘보면 여기에 "second ago" 라는 말이 보인다 즉 뭔가 계산을 잘못해서  계속 second ago를 출력하고 있었다는 말이다.

우리가 고쳐야 할 부분은 22~27행 사이만 보면 된다.
여기에 나오는 replace( ) 함수는 문자열에서 특정 문자를 치환하거나 삭제하는 등의 가공을 하는 함수로 아까 선택했던 "mm/dd/yyyy hh:mm:ss 오전" 형식에 나오는 슬레시 같은 특수문자 같은것을 제거해서 원하는 형태의 문자열로 가공하는 부분이다.

분명히 코드에는 문제가 없을 것이다. 그럼 무슨 문제일까?

필자는 코드 수정 전에 실험을 하면서, 타임스탬프 형식을 날짜만 나오는 "mm/dd/yyyy" 형식으로 바꿨을때 조금 비정상 적이긴 하지만 second ago라는 문자 대신 1 days 라고 표시되는걸 확인했었다. 

자료를 찾다가 외국 블로거의 포스팅을 찾다보다 불현듯 든 생각, 다른 부분이 딱 하나 있었다. 국적이 영어권이면 오전 / 오후 가 아닌 AM / PM 으로 표시 된다는 것이다. 영어는 문자 하나를 1바이트로 표현하지만 한글은 2바이트로 표현한다. 즉 코딩된 함수에 들어온 게시일자 문자열의 길이가 달랐던 것이다.

그래서 저 코드 중 일부를 수정을 하려 했지만 내 머리로는 도저히 이해가 안갔다. 그래서 아는 만큼 작업을 했다. 기존 코드를 수정하기 보단 "오전 / 오후" 를 "AM / PM" 으로 치환하는 함수를 추가 하기로 했다.

replace( ) 함수가 문자열중 특정 문자를 치환하는 함수이기 때문에 아래와 같은 코드를 추가했다.


 time = time.replace('오전', 'AM').replace('오후', 'PM'); 


삽입 위치는 if (!time) return; 바로 뒤에 하면 되고 삽입된 코드는 아래와 같다.


var timer = function(time) {
    if (!time) return; time = time.replace('오전', 'AM').replace('오후', 'PM');
    time = time.replace(/\.\d+/, "");
    time = time.replace(/-/, "/").replace(/-/, "/");
    time = time.replace(/T/, " ").replace(/Z/, " UTC");
    time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2");


실제로는 다 붙어있는 코드라서 찾기 좀 복잡할 것이다.

저 한 줄의 코드를 추가하고 정상 작동을 한다. 코드를 수정했으면 반드시 저장을 누르자.


5. 마치며

사실 저 코드 한 줄 추가 하라고만 적어도 될 일을 조금 장황하게 적었다. 이유는 필자처럼 HTML이나 자바스크립트에 약한 사람들이 많을텐데 테마의 종류는 많고 문제가 생겼을때 물어볼 사람도 없다. 결국 수많은 검색과 실험으로 테마를 고쳐 나갈텐데

필자가 겪은 시행착오를 보면서 뭔가 문제가 생겼을때 어떻게 고쳐나가야 하는지 과정도 조금 보여주고 싶었다.

조금이라도 도움이 되었길 바란다.



댓글 쓰기

다음 이전