페이지

Posts List

레이블이 구글인 게시물을 표시합니다. 모든 게시물 표시
레이블이 구글인 게시물을 표시합니다. 모든 게시물 표시

2014년 8월 23일 토요일

웹 사이트는 소프트웨어일까?

웹 사이트는 소프트웨어일까?


1999년에 한국HCI연구회에 ‘웹 사이트 공학‘ 이란 제목의 칼럼을 올렸었고, 2005년도에 블로그에옮기면서 다시 생각을 한 적이 있었다.
그때의 내 논지는 웹 사이트를 소프트웨어가 아니라 미디어로 보고 주먹구구식으로 만들었기 때문에 라~아지 스케일의 웹 사이트는 엉망이 되어 간다는 것이었고,  이를 해결하기 위해서 전산학의 소프트웨공학에서 개발 방법론을 빌려 오자는 얘기를 했었다.
오늘 사내에서  스크럼이라는 애자일 방법론에 대한 강의를  들었다. 프랑스 사람이 쉬운 영어로 얘기를 해주었지만 수학  공식에서는 잘 이해를 하지는 못했다.
이 강의를 들으면서 문득 1999년도에 했던 생각이 다시 났다. 컴퓨터 기술로 만들어졌기 때문에 웹 사이트는 소프트웨어일까? 아니면 뉴미디어일까? 아니면 새로운 상거래 방법일까?
웹 사이트 개발(기획 부터 모든 것 다)의 책임자는 소프트웨어 개발자일까? 아니면 웹 기획자일까?
왜 소프트웨어 엔지니어들은 이렇게 개발방법론을  기획자들을 대상으로 아트를 하고 있을까? 제품의 오너가 웹 기획자이기 때문일까?
그럼 웹 기획자는 소프트웨어 공학이나 제품 개발 방법론에 대해서 얼마나 잘알까? 인터넷 서비스 기획자의 자격 조건은 있기는 한 것일까?
인터넷 웹 사이트 개발은 전산학의 소프트웨어 범위를 벗어 난다. 개발을 단순히 프로그램 언어로 컴퓨터 상에서 작동하도록 하는 것이 아니라면 말이다. 그 이유는 기존 소프트웨어 공학에서는  HCI나  마케팅, 비지니스 모델, 시장 논리가 없기 때문이다.  리서치와 기술, 시장으로 부터 아이디어를 얻고 컨셉을 만들고, 시장성을 보는 등의 과정과 컨텐츠 저작과 운영까지도 포함해야 한다. 소프트웨어는 알고리즘과 데이타이지만 전산쟁이들은 데이타는 다루지 않고 규칙만 다르기 때문에 컨텐트에 대한 저작과 운영이 포함되어야 한다.
인터넷 회사에서 보면 웹 기획자가 제품의 제품 관리자가 되고,  프로젝트 관리자가 되는 것 같다. 소프트웨어 엔지니어들은 기술 구현 안에서의 프로젝트만  관리한다.  내가 인터렉션 디자이너를 데리고 있었을 때에는 인터렉션 디자이너가 제품 개발의 전체 개발 일정을 관리했다. 인터렉션 디자이너는 누구에게 줄 어떤 제품을 만들고 그 내용이 무엇인지를 다루기 때문에 당연한 것이다. 그러나 이 또한 엔지니어는  인터렉션 디자이너가 정한 스펙을 구현하기 위한 구현 일정만 다루게 된다.
어째 요즘 추세가 그런것인지 아니면 인터넷이라서 그런 것인지는 모르겠지만 웹 사이트 개발에서 엔지니어는 웹 사이트를 만드는 것이 아니라 웹 사이트를 컴퓨터 기술로 구현만 하는 것 처럼 보인다.  그래서 그들이 하는 프로젝트 관리의 범주에는 사용자 니즈 조사가 없고 정해진 요구사항 스펙을 기술 스펙으로 바꾸고 그것을 구현해서 테스트 하는 것만 다루는 것 같다. 이런 것을 만들어 보면 어떨까?  제안을 해서 이런 것이 니네한테 필요하고 이렇게 만들어 주겠다고 하는 것들은 인터넷 웹 사이트 개발에서는 더 이상 소프트웨어 엔지니어들의 역할이 아닌걸까?
웹 사이트는 소프트웨어일까?
웹 사이트를 무엇으로 보느냐에 따라서 제품개발의 오너가 달라질 수도 있을 것 같다.  소프트웨어라면 소프트웨어 엔지니어가 제품 관리자가 되어야 할 것이다. 만약 비지니스나 쇼핑, 뉴스와 같은 도메인에 대한 지식과 경험이 더 중요하다면 그런  내용을 전문으로 하는 사람이 제품 오너가 될 것이다.
그러나 둘 다는 둘다를 다 잘하지 못한다.  기자 출신의 인터넷 뉴스 제품 관리자는 제품 전략이나 마케팅, 제품 개발 방법론, 기술, 사용자, UI에 대해서 전문가가 아니고,  엔지니어가 제품 관리자를 하면 비지니스, 도메인 업계, 경영, 시장,마케팅, UI, 사용자를 모를 것이다.
그러나 결과를 보면 인터넷 기업은 만드는 것 자체인 동사가 아니라 비지니스를 책임지는 명사 위주로 제품의 오너쉽을 주는 것 같다. 웹 사이트는 만드는 측면에서는 소프트웨어이지만 경영 측면에서는 비지니스 도메인 영역이다. 즉, 인터넷 뉴스, 인터넷 쇼핑이다.
결국 결론은 버킹~검. 세상은 혼자 할 수 있게 별로 없으니 전문가들이 잘 협업해서 만들어라~

Web 개발방법의 변천, 2012

[Tech] Web 개발방법의 변천 Tech

** 
나름 깔끔하게 구분해 놓은듯..


웹 표준 시대(2000년대 초반)

2000년대 초반으로 오면서 백엔드 개발에서는 이른바 MVC 모델이라는 기법을 통해 데이터 모델과 템플릿 그리고 비즈니스 로직이 분리된 코드를 통해 개발 생산성을 높이게 된다.
프론트엔드에서도  표준 개발 방법론을 통해 구조(HTML)표현(CSS)동작(DOM Script) 분리하고 CSS 레이아웃과 W3C 기반 DOM 통한 웹 개발 방식을 많이 이용하게 된다.

국내에서는 대략 2004년부터  표준 기반 프론트엔드 개발 방식이 도입되기 시작했으며 주요 포털을 비롯하여 민간 기업  공공  사이트에 웹 접근성과 더불어 확산되게 된다이를 통해 국내에서도  퍼블리셔를 중심으로  직군이 형성되었다.

web1.png


Ajax 시대 (2000년대 후반)

2004 지메일과 구글맵스가 소개되면서 프론트 엔드 부분의  기술의 혁신 일어나게 된다프론트엔드  콘텐츠가 고객의 PC 일단 로딩이   서버에 Ajax 호출을 통해 데이터를 받아   기존 DOM 갱신하는 개발 방법이다.
 방법을 통하면 백엔드 개발자가 json 같은 데이터 기반 응답만 하게 되므로  간단한  개발이 이루어진다이에 반해 프론트엔드 개발자는 다양하고 풍부한 사용자 경험을 제공하는  애플리케이션 개발이 가능해졌다.
하지만 방식의 경우도 여전히  서버에 종속적으며 독립적인  애플리케이션 개발은 가능하지 않다.

web2.png


HTML5시대 (2010년대 초반)

HTML5 가져올 가장  변화는 서버와 독립적인  애플리케이션의 개발이 가능하다 대목이다특히모바일 환경에서 오프라인 기능과 로컬 데이터베이스의 지원  서버와 독립할  있는 여건을 만들어 준다.

특히, HTML5 Canvas, 드래그앤드롭지오로케이션파일API 등을통한 사용자 경험을 확대해   있다구글의 경우웹스토어라는 새로운 웹 애플리케이션 마켓플레이스를 준비하고 있기도 하다.
게다가 백엔드 부분의 기술적 변화도 눈에 띈다기존의 RDBMS와 MVC 기반 플랫폼에서 늘어나는 데이터를  처리하기 위해 RESTful한 데이터 통신을 제공하고데이터는   빠른 분산 파일 스토리지에 저장하는 방법이다구글아마존페이스북트위터가 이미 이러한 방식으로 웹 서비스를 제공하고 있기도 하다.
향후 5년간 다양한  기술 요소들이  개발 방법론  플랫폼을 변화시킬 것으로 예상된다간단한 프로토타입을 자사의 서비스에 조금씩 도입함으로서 새로운 변화가 연착륙할  있도록 하는 노력이 필요하다.


web3.png


2014년 8월 21일 목요일

구글 블로그(blogger) 본문 요약 및 이미지 썸네일 처리하기

http://ielselog.blogspot.kr/2013/09/post-summary-with-thumbnail.html


구글 블로그(blogger) 본문 요약 및 이미지 썸네일 처리하기

아래는 데모 블로그에서처럼 홈에서 본문을 요약 처리하고 이미지가 있는 경우 이미지를 썸네일로 보여주는 자바스크립트 코드입니다.

데모 보기

 <script type='text/javascript'>  
summary_noimg = 600;
summary_img = 600;
img_thumb_height = 250;
img_thumb_width = 350;
</script>
<script type='text/javascript'>
//<![CDATA[
function removeHtmlTag(strx,chop)
{
if(strx.indexOf("<")!=-1)
{
var s = strx.split("<");for(var i=0;i<s.length;i++){if(s[i].indexOf(">")!=-1){s[i] = s[i].substring(s[i].indexOf(">")+1,s[i].length);}}strx = s.join("");}
chop = (chop < strx.length-1) ? chop : strx.length-2;while(strx.charAt(chop-1)!=' ' && strx.indexOf(' ',chop)!=-1) chop++;strx = strx.substring(0,chop-1);return strx+'...';}
function createSummaryAndThumb(pID){
var div = document.getElementById(pID);
var imgtag = "";
var img = div.getElementsByTagName("img");
var summ = summary_noimg;
if(img.length>=1) {imgtag = '<span style="float:left; padding:0px 10px 5px 0px;"><img src="'+img [0].src+'" width="'+img_thumb_width+'px" height="'+img_thumb_height+'px"/></span>';
summ = summary_img;
}
var summary = imgtag + '<div>' + removeHtmlTag(div.innerHTML,summ) + '</div>';
div.innerHTML = summary;
}
//]]>
</script>

코드의 일부 내용들은 자신의 스타일에 맞게 변경이 가능합니다.

 summary_noimg = 600;  
포스트에 이미지가 존재하지 않을 때 요약 페이지에 표시하게 될 글자 수

 summary_img = 600;  
포스트에 이미지가 존재할 때 요약 페이지에 표시하게 될 글자 수

 img_thumb_height = 250;  
요약 페이지에 표시될 썸네일 이미지의 높이(height)

 img_thumb_width = 350;  
요약 페이지에 표시될 썸네일 이미지의 너비(width)

 <span style="float:left; padding:0px 10px 5px 0px;">  
썸네일과 요약 텍스트 사이의 간격을 조절하고 싶다면, 여기서 패딩 부분 조정하면 됩니다.

자신의 스타일에 맞게 코드를 변경했다면, [대시보드 → 템플릿 → HTML편집] 으로 들어가서 검색으로 </head> 태그를 찾은 후 </head> 바로 위에 해당 코드를 복사하여 붙여넣기합니다.

그리고나서,

 <data:post.body/>  

이 코드를 조건 태그로 바꿔주어야 합니다.

  • 기본 템플릿(구식 템플릿)
  • 동적뷰 템플릿
  • 어디선가 다운받은 템플릿

위 세가지 템플릿이 아닌, 블로거에서 제공하는 '깔금', '풍경', '세련', '무늬', '초현실', '여행' 템플릿을 수정하여 쓰고 있을 경우, Ctrl+F로 이 코드를 찾으면, 총 3개가 발견됩니다.


이 중 첫번째는 모바일 영역이니 건들지 마시고, 두번째에 보이는

 <data:post.body/>  

코드를 아래의 코드로 대체해줍니다.

 <b:if cond='data:blog.pageType != &quot;static_page&quot;'>  
<b:if cond='data:blog.pageType != &quot;item&quot;'>
<div expr:id='&quot;summary&quot; + data:post.id'>
<data:post.body/>
</div>
<script type='text/javascript'>createSummaryAndThumb
(&quot;summary<data:post.id/>&quot;);</script>
<div class='readmore-wrap'>
<span class='rmlink' style='font-weight:bold;padding:5px;float:right;text- align:right;'>
<a expr:href='data:post.url'>더 보기&#187;</a>
</span>
</div>
</b:if>
</b:if>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
<data:post.body/>
</b:if>
<b:if cond='data:blog.pageType == &quot;static_page&quot;'>
<data:post.body/>
</b:if>

모두 완료되면, '템플릿 저장'을 클릭해 줍니다.


코드의 출처는 mytutorialscafe.com 이라는 해외 블로그입니다. 코드 적용 전에는 반드시 백업을 해두시고, 또 테스트용 블로그에서 충분한 테스트를 해본 후 사용하시기 바랍니다.

2014년 8월 16일 토요일

구글 블로그 (Blogspot)의 글 (post)을 백업하는 도구들

구글 블로그 (Blogspot)의 글 (post)을 백업하는 도구들

  2 Comments
구글 블로그 (Blogspot)의 포스트들을 백업하는 방법에 대해서 소개하겠습니다.
첫 번째 방법은 Blogger Backup 이라는 open-source 도구를 사용하는 방법입니다.
“Blogger Backup”은 포스트와 포스트에 달린 댓글들을 함께 PC로 저장할 수 있습니다. 구글 계정을 입력하고 백업하고 싶은 포스트를 선택하기만 하면 됩니다.
(※ 작은 open-source 프로그램이기 때문에 비밀 번호를 다른 곳으로 전송하는지는 코드를 확인하면 체크할 수 있을 것입니다)
물론, 모든 포스트를 저장하는 옵션도 겸비하고 있습니다.
일단 포스트를 PC로 저장 하고 나면, DB에 import할 수도 있고 Blogger’s API를 이용해서 새로운 블로그를 만들 때 포스트를 올릴 수도 있습니다.
그리고 이 툴은 Blogger’s API를 이용해서 feed를 가져올 수 있습니다. ^^
아래는 스크린샷입니다.

위 툴은 아래 링크에서 받아 공짜로 받아 볼 수 있습니다.
http://www.codeplex.com/bloggerbackup
두 번째 방법은 우리의 FireFox의 Add-on인 DownThemAll을 이용하는 방법입니다.
아래 주소를 클릭하시면 Add-on을 다운 받을 수 있는 페이지가 열립니다.
https://addons.mozilla.org/firefox/201/
블로그 포스트에 있는 그림들을 다운로드 받는데도 아주 유용합니다.
그리고 XML feed에 있는 모든 포스트를 다운로드 받을 수 있는 멋진 (? ^^) 기능도 제공한다고 합니다.
구글의 BlogSpot을 사용하시는 분들에게는 유용한 도구인 것 같습니다. ^^

2014년 8월 10일 일요일

Gadgets for Blogger

https://developers.google.com/blogger/docs/gadgets/gadgets_for_blogger

Gadgets for Blogger

At Google, gadgets are simple HTML and JavaScript applications that can be embedded in web pages and other apps, including Blogger.
When you build a gadget for Blogger, it becomes available to millions of active bloggers. Just submit your gadget to us, and it will surface in Blogger.com where users can easily browse, configure, and add your gadget to their blog's sidebar.
So now that you know Blogger is a great distribution platform for your gadget, what are you waiting for? Get started building gadgets for Blogger now!

Get Started

Gadget Developer GuideIn their simplest form, gadgets for Blogger are "Google Gadgets". If you aren't familiar with Gadgets yet, take a look at the Developer Guide to get started.
Accessing Blog Data from the GadgetBlogger's JSON APIs give gadgets access to a blog's post and comment data, letting them leverage the context of the surrounding content.
Best UI Practices for Bloger GadgetsBest practices for making your gadget look good across the large set of blog styles and layouts.
Example GadgetA simple example gadget implementing best practices.
Testing your gadget in BloggerHow to test your gadget in Blogger.
Submit your gadget to BloggerNow that your gadget is bug-free and beautiful, tell the world about it!

Accessing Blog Data from the Gadget

Blogger provides read-only blog data access to gadgets. The API retrieves public post and comment data for the blog hosting the gadget. Developers can opt to retrieve the data directly in Blogger's JSON format, or retrieve the URL of the underlying Atom feed for future use.
The API is available as the google.blog feature; a gadget that depends on the data can require this feature. If you'd like your gadget to optionally access blog data but still be compliant with other Google Friend Connect containers you can make the feature optional.

Blog Posts

getPostsJson(callback)
Retrieves feed of recent posts for the current blog, returning it as JSON to the callback.
getPostsFeedUrl()
Returns the URL of the Atom feed of all posts for the current blog.

Blog Comments

getCommentsJson(callback)
Retrieves feed of recent comments (across all posts on the blog), returning it as JSON to the callback (format documented here).
getCommentsFeedUrl()
Returns the URL of the Atom feed of all recent comments.

The Current Blog Post

When a gadget is being displayed on an individual post page, these methods access the data for that post. If the gadget is not on an individual post page, these return null. You can use getCurrentCommentsFeedUrl()!=null as a test to indicate the gadget's environment.
getCurrentPostJson(callback)
Retrieves the current post as JSON, or null if there is none.
getCurrentCommentsFeedUrl()
Returns the URL of the Atom feed for recent comments on the current post, or null if there is no current post.
getCurrentCommentsJson(callback)
Returns the feed of recent comments for the current post, returning it as JSON to the callback (format documented here).

Example Snippet Accessing Blog Data

This snippet calculates the word count for the various authors on a blog based on the last few posts, using each author's OpenSocial ID as a key for ease of lookup later.
...

// Calculate wordiness of blog authors:
function onLoadFeed(data) {
if (data.rc != 200) {
w(["Error loading blog data"]);
return;
}
var feed = data.data.feed;
var word_counts = new Array();
var wordiness = new Array();

for (var i = 0; i < feed.entry.length; i++) {
var entry = feed.entry[i];
var word_count = entry.content.$t.split(/\s/).length;
var osid = getOpenSocialId(entry.author[0]);
var author = entry.author[0].name.$t;
var authorid = getOpenSocialId(entry.author[0]);
var key = [author,authorid];
if (wordiness[key]==undefined)
wordiness[key] = word_count;
else
wordiness[key] += word_count;
}

var disp = new Array();
for (var k in wordiness) {
disp.push(k + " : " + wordiness[k] + " words");
}
w(disp);
}

// Return the OpenSocial ID for an author if available
function getOpenSocialId(person) {
var extendedProperty = person.gd$extendedProperty;

if (extendedProperty && extendedProperty.name == "OpenSocialUserId") {
return extendedProperty.value;
} else {
return null;
}
}

// Write output to a display element on the gadget
function w(arr) {
var str = "<ul>";
for (var e in arr) {
str += "<li>"+arr[e]+"</li>";
}
str += "</ul>";
document.getElementById('display').innerHTML = str;
}

Best UI Practices for Blogger Gadgets

Bloggers want to look good on the web. Follow these best practices so your gadget blends seamlessly with the many themes bloggers use.

Support A Range of Widths

In Blogger, the available width for your gadget depends both on the blog's template, and on the location where the gadget is inserted in the blog. The sidebars in Blogger.com templates range from 150px - 360px wide, though some templates have sidebars that resize to be wider when the browser window is stretched. In addition blog administrators can overwrite the default sidebar width.
In addition, gadgets can be added to the blog's side bar, header, or footer regions as shown by the orange rectangle in the images below.
                
This means your gadget should be flexible to work well at almost any width. Be sure to test your gadget in a variety of sizes in the blog before submitting your gadget.

Managing Gadget Height

By default, gadgets are 200 pixels high. You can use the <ModulePrefs> attribute height="nn" to specify a static height that is bigger or smaller than the default. However most gadgets will need to dynamically change their height. Follow these guidelines to dynamically resize the height of your gadget.

Inherit the Blog's Style

The skins feature provides access to key Blogger theme parameters. This feature is shared between Blogger and Google Friend Connect and the same skin parameters are used in both. In Blogger, the parameters are automatically inherited from the blog's template, so gadgets can easily blend in with the look and feel of the containing page. Blog owners can also override skin values if they wish to do so.
To access the parameters, a gadget asks for the skins feature:
<Optional feature="skins" />
It can then access parameters via the API, setting styles of elements via DOM manipulation:
<$("someElement").style.borderColor = gadgets.skins.getProperty('BORDER_COLOR');

Core Skin Parameters

These parameters are the most critical to use, and are always provided by the container. Each of these maps to an equivalent CSS style and can be added to HTML elements.
BORDER_COLOR
Color of border of gadget, or 'transparent' if no border desired. Use this for the style of any border around the entire gadget; do not assume that the border is always visible (many blogs do not frame gadgets with borders).
CONTENT_BG_COLOR
Background color to use for main portion of gadget. This usually matches the background color of the blog's sidebar, but in any case is chosen by the container to make gadgets look good.
CONTENT_LINK_COLOR
Color of links in the main portion of gadget; chosen by the container to be readable against CONTENT_BG_COLOR, work well withCONTENT_TEXT_COLOR, and be consistent with links elsewhere on the page.
CONTENT_TEXT_COLOR : Color of primary or most-displayed text in main portion of gadget; chosen by the container to be readable againstCONTENT_BG_COLOR and consistent with text on the rest of the page.
FONT_FACE
Font face to use by default; chosen to be consistent with the rest of the content.

Extended Skin Variables

These may be used by a page owner to further tweak appearance on a per-gadget basis. They are not needed for all gadgets, but if your gadget uses these concepts, it should allow these variable to control their style.
CONTENT_HEADLINE_COLOR
Text color for titles or headlines as opposed to body text. Defaults to CONTENT_TEXT_COLOR.
CONTENT_SECONDARY_TEXT_COLOR
An alternative color for secondary text that complements CONTENT_TEXT_COLOR. Defaults to CONTENT_TEXT_COLOR.
CONTENT_SECONDARY_LINK_COLOR
Color for links in secondary text. Defaults to CONTENT_LINK_COLOR.
ENDCAP_BG_COLOR
Color for top and bottom cap sections for the gadget; defaults to CONTENT_BG_COLOR.
ENDCAP_LINK_COLOR
Color for links within top / bottom cap sections; defaults to CONTENT_LINK_COLOR.
ENDCAP_TEXT_COLOR
Color for text within top / bottom cap sections; defaults to CONTENT_TEXT_COLOR.
ALTERNATE_BG_COLOR
Used for alternating rows in large list; defaults to CONTENT_BG_COLOR
CONTENT_VISITED_LINK_COLOR
Visited link color; defaults to CONTENT_LINK_COLOR.

Using Canvas Mode

To create a canvas("big mode") view of your gadget, where the gadget expands horizontally to span the entire gadget area, you must define a section for the "canvas" view type, as follows:
<Content type="html" view="canvas" />

Keep it simple

Each element, style, or graphic you add to your gadget, is something else that might clash with the containing blog's style. You want your gadget to blend seamlessly into as many blogs as possible. Avoid adding elements that cannot be skinned using the above defined skin parameters.
Do not add a title into your gadget's UI. Blogger will add the title automatically outside of the gadget in the same style as other gadget titles on the blog.
Most importantly, test your gadget on a number of different blogs. Modify the blog's background color, text color, and font face to ensure your gadget blends with a wide range of templates.

Example Gadget

Here is a very simple Friend Connect powered gadget that takes advantage Blogger's JSON API. The gadget displays the current post's comments and highlights the comment if it was made by the viewer's friend. When the gadget is embedded in a blog, it will match the blog's style because it inherits several skin parameters.
The example gadget is also hosted here: example gadget.
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs height="300" title="BlogSocial">
<Require feature="opensocial-0.7"/>
<Require feature="google.blog"/>
<Require feature="skins"/>
<Require feature="views"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
var friendProfiles = {};
var blog;

function goToCanvas() {
var view = gadgets.views.getSupportedViews()['canvas'];
gadgets.views.requestNavigateTo(view);
}

/**
* This method is called after your friend data is loaded. It parses the friend data and
* saves the profile ids of your friends, then fetches the blog data.
*/
function onLoadFriends(data) {
if (data.responseItems_.viewerFriends.data_ == null) {
document.getElementById("output").style.textAlign = "center";
if (gadgets.views.getCurrentView().getName() == "canvas") {
document.getElementById("output").innerHTML = 'Sign in using the link above';
} else {
document.getElementById("output").innerHTML =
'<a style="color:' + linkColor + '" href="javascript:void(0);"
onclick="goToCanvas();">Sign in to Friend Connect!</a>';
}
return;
}

var friends = data.responseItems_.viewerFriends.data_.array_;
for (var i = 0; i < friends.length; i++) {
var id = friends[i].fields_.id;
friendProfiles[id] = "true";
}

// Get the feed data
blog = new google.Blog(function() {
// This callback is run as part of the constructor of google.Blog to signify
// that everything was initialized. Once the constructor has
// completed and then call getCommentsJson
blog.getCommentsJson(onLoadFeed);
}, window.name);
}

/**
* This method parses the feed data that was returned by the call to fetch the blog data.
*/
function onLoadFeed(data) {
var list = document.getElementById("output");

if (!data.data) {
list.innerHTML = "An error occured fetching the feed data";
}

data = data.data;

if (!data.feed.entry || data.feed.entry.length == 0) {
list.innerHTML = "No comments on this blog!";
}

for (var i = 0; i < data.feed.entry.length; i++) {
var entry = data.feed.entry[i];
var dt = document.createElement("DT");
dt.style.paddingTop = "10px";
var dd = document.createElement("div");
var href;
for (var j = 0; j < entry.link.length; ++j) {
if (entry.link[j].rel == "alternate") {
href = entry.link[j].href.replace(/#/, "#comment-");
}
}

var a = document.createElement("A");
a.style.color = linkColor;
a.setAttribute("href", href);
a.appendChild(document.createTextNode(entry.author[0].name.$t + " wrote..."));
dt.appendChild(a);
dd.appendChild(document.createTextNode(entry.content.$t));
list.appendChild(dt);
list.appendChild(dd);

// extendedProperty is Blogger's extension to ATOM 1.0 that contains the
// OpenSocial user id of the author if the author is a public follower
// of the blog. This field will not be present if the author is not a
// public follower of the blog.
var extendedProperty = entry.author[0].gd$extendedProperty;

if (extendedProperty && extendedProperty.name == "OpenSocialUserId") {
if (friendProfiles[extendedProperty.value]) {
dt.style.backgroundColor = "yellow";
dd.style.backgroundColor = "yellow";
}
}
}
}

var linkColor;
var textColor;
var backgroundColor;
function initData() {
textColor = gadgets.skins.getProperty('CONTENT_TEXT_COLOR');
document.getElementById("output").style.color = textColor;

linkColor = gadgets.skins.getProperty('CONTENT_LINK_COLOR');
document.getElementById("canvas-link").style.color = linkColor;

backgroundColor = gadgets.skins.getProperty('CONTENT_BG_COLOR');
document.body.style.backgroundColor = backgroundColor;

// Show canvas mode link if appropriate
if (gadgets.views.getCurrentView().getName() != "canvas") {
document.getElementById("canvas-link-container").style.display = "block";
}

var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS', {}), 'viewerFriends');
req.send(onLoadFriends);
}
gadgets.util.registerOnLoadHandler(initData);

</script>
<div style="display:none;float:right;font-size:80%" id="canvas-link-container">
<a id="canvas-link" href="javascript:void(0);" onclick="goToCanvas();">Canvas mode</a>
</div>
<div style="clear:both"></div>
<div id="output" style="overflow:auto; height:270px;font-size:90%"></div>
]]>

</Content>
</Module>

Testing your Gadget in Blogger

Since a gadget for Blogger is a Google Gadget, follow this guide for testing and preparing your Google Gadget for publication. One complete, read and follow the sections below describing how to test your gadget in Blogger.

Setting up a Test Blog

Create a test blog with some post and comment data to use during testing:
  1. Download test_blog_data.xml.zip; uncompress the file and save test_blog_data.xml to your computer.
  2. Go to the Import Blog Page
  3. Upload test_blog_data.xml and follow the instructions to import the blog content and publish it.
Now you're ready to start testing.

Debugging your gadget in Blogger

The functionality and appearance of your gadget depends on the blog that contains it. Therefore, the best way to debug your gadget is to test it in the context of an actual blog on Blogger.com. Above we described how to create a test blog, below we discuss how to add your gadget to your test blog and debug it on the blog.
First, make sure that your gadget XML file is hosted on a public web server, and that you have a test blog set up. From Blogger.com, go toLayout -> Add a Gadget ->Add your Own, enter your gadget's URL, and then save. The gadget will be added to your blog; click View Blog to view and test your gadget in the blog.

Testing Gadget Configuration in Blogger

Blogger provides a standard UI for adding and configuring gadgets. You should test that any UserPrefs you've defined can correctly be configured by the blog administrator in Blogger.com.
From Blogger.com, click the Layout tab, then click Add a Gadget. From the Gadget Diretory, choose Add your own. This allows you to add your gadget by its URL (note: the gadget must be hosted on a public web server).
When you add a gadget, it will display a preview and show any UserPref parameters that can be configured. Test updating various configuration values and adding your gadget to your test blog. Confirm your gadget works as expected on the blog itself.

Testing Width and Height

In Blogger, the available width for your gadget depends on the location it is inserted. Gadgets can be added to the blog's side bar, header, or footer regions as shown by the orange rectangle in the images below.
                
From Blogger.com, click the Layouts tab for your test blog. Drag your test gadget into the following regions, and click Save to view and test your gadget in those locations.
  • side bar
  • header area
  • footer area
Also test the gadget in the sidebar of several different templates, since sidebar widths vary from template to template. From Blogger.com, click the Layout tab for your blog. Then click Pick a new Template. From the Template Picker, test that your gadget works well in the side bar of these templates:
  • Scribe (150px sidebar)
  • Rounders (215px sidebar)
  • Tekka (360px sidebar)
  • Denim Stretch (variable widgth sidebar)

Testing Style, Fonts and Colors

As described above, your gadget should use skinning parameters to inherit the blog's style including text colors, background colors, and font face. Test that your gadget correctly inherits the blog's style by testing it on a variety of different blog templates.
From Blogger.com, click the Layout tab. Then click Pick a new Template. From the Template Picker, confirm your gadget correctly inherits styles from the following templates:
  • Minima Dark
  • Denim
  • No. 897
  • Rounders
  • The more the better!
You may want to also edit the blog's Fonts and Colors directly. From the Layouts tab, click Fonts and Colors to control specific font and color choices for the blog and verify they are correctly inherited by your gadget.

Submit your gadget

Once you've throughougly tested your gadget, and followed Blogger's Best UI Practices, you're ready to submit your gadget.