행위

미디어위키 확장 extention 활용가이드

DB CAFE

thumb_up 추천메뉴 바로가기


1 MediaWiki Extention ,기능 확장[편집]

  1. Extention은 글를 쓰기 위해 사용되는 wiki 마크업에 새 태그를 추가하고
  2. 특수 페이지를 작성하여 새로운 보고와 관리 기능을 추가하며
  3. 형식화 스킨을 통해 wiki의 룩앤드필을 변경하며
  4. 외부 인증 메소드와 통합할 수 있다
  • Extention 은 PHP로 작성되며 MediaWiki의 다양한 내부 연결, 클래스 및 메소드를 활용하여 그 임무를 효과적으로 수행한다.

1.1 Extention 위치/파일구조[편집]

  1. MediaWiki Extenion은 기본 MediaWiki 경로에서 extention 디렉토리에 설치된다.
  2. 대부분의 Extention은 개별 디렉토리에 설치되고 3개의 파일로 구성된다(extension은 확장의 이름이다).
    1. /extension/익스텐션명/extension.php
      파일은 초기화와 설치 태스크를 수행
    2. /extension/익스텐션명/extension.body.php
      확장의 본문이며, 확장을 구현하는 작업 코드
    3. /extension/익스텐션명/extension.i18n.php
      국제화(i18n은 일반적인 짧은 양식이다) 문자열이 포함된다
  • 확장의 메시지 스트링을 i18n 파일로 요약하여 모든 MediaWiki의 지원되는 로케일을 위한 확장의 현지화된 버전을 제공할 수 있다

1.1.1 예제) CHTimeStamp이라는 Hello World 확장의 종류 작성[편집]

  • (이 기사의 이 예제 및 다른 예제에 대한 소스 코드는 다운로드를 참조).
  • CHTimeStamp는 누군가가 wiki 페이지에 틀:CHSTAMP를 삽입할 때마다 현재 날짜/타임스탬프를 삽입 한다.
1.1.1.1 파일 구성[편집]
  1. CHTimeStamp/CHTimeStamp.php
  2. CHTimeStamp/CHTimeStamp.body.php
  3. CHTimeStamp/CHTimeStamp.i18n.php
  • CHTimeStamp 확장은 MediaWiki의 마크업에 틀:CHSTAMP 변수 추가.
  • 페이지에 틀:CHSTAMP를 넣을 때마다 이는 날짜/타임스탬프로 대체된다.
1.1.1.2 파일 역활/상세 설명[편집]
  1. CHTimeStamp.php는 국제화 메시지 파일을 등록
    1. wiki 엔진에 이 파일이 CHTimeStamp 클래스를 CHTimeStamp.body.php에서 찾을 수 있다고 알려준다
    2. CHTimeStamp::registerHooks 메소드를 확장 함수의 배열에 추가한다.
  2. CHTimeStamp.body.php에서 CHTimeStamp 클래스를 정의한다.
    1. 코드를 살펴보면 이는 전체적으로 정적 메소드로만 만들어져 있기 때문에, 확장의 작동을 변경하지 않고 함수의 시리즈로도 쓰여질 수 있었다.
    2. CHTimeStamp의 registerHooks 메소드는 정적 메소드를 등록하여 틀:CHSTAMP 변수를 작성하고 이를 사용하는 페이지를 핸들링한다.
  3. CHTimeStamp.i18n.php에서 확장의 유일한 정적 문자열인 설명에 대한 해석을 작성하였다.
    1. Google Translate의 도움을 받아 CHTimeStamp는 프랑스어, 독일어 및 스페인어 로케일을 지원한다.

1.1.2 Extention 을 MediaWiki에 설치하기[편집]

  1. MediaWiki의 루트 디렉토리에서 LocalSettings.php를 편집
    1. PHP의 require_once() 명령문을 사용하여 이를 활성화
      - 예를 들어 CHTimeStamp를 설치하기 위해 CHTimeStamp 디렉토리를 확장 디렉토리에 복사하였고 다음 require_once( "$IP/extensions/CHTimeStamp/CHTimeStamp.php" );를 LocalSettings.php에 추가.
  2. ”wiki 검색창“ 에 Special:Version 페이지를 입력하고 익스텐션이 로드되었는지 확인.
    * Special:Version 페이지가 실행 중인 MediaWiki 버전에 대한 정보 이외에도 로드한 확장을 나열한다.
    20101117_44_2.jpg

1.1.3 룩앤드필 사용자 정의하기[편집]

  1. MediaWiki는 스킨의 사용을 통해 wiki의 룩앤드필 전체에 대한 제어를 제공하기 위해 코드와 HTML 마크업을 혼합하는 PHP의 기능을 활용한다.
  2. 기본 PHP 코드 이외에도 스킨은 다양한 CSS 파일과 지원하는 이미지 또는 JavaScript를 포함할 수 있다.
  3. 스킨은 일반적으로 두 개의 PHP 파일과 하나의 추가 지원 파일을 위한 디렉토리로 구성된다.
    1. 예를 들어 유명한 기본 스킨인 MonoBook은 다음으로 되어 있다.
      -MonoBook.php ― 기본 MonoBook 스킨 코드
      -MonoBook.deps.php ― PHP V5의 APC 연산 코드 캐시에서 버그를 위한 수정사항
      -monobook/ ― 지원하는 CSS와 그래픽
  4. 스킨의 이름 지정 규칙은 매우 엄격하여, 지원 폴더 이름으로 SkinName.php, SkinName.deps.php 및 skinname(소문자)가 필요하다.
    1. skinname 폴더 내에 스킨의 스타일링을 위한 main.css가 있을 것이다.
    2. 브라우저별 스타일시트 수정사항도 여기에 소속되어 있기 때문에 때로는 FF2Fixes.css, IE6Fixes.css, Opera6Fixes.css 등을 찾을 수 있다.
1.1.3.1 SkinName.php[편집]
  • 일부 유용한 메타데이터로 동작

1) MediaWiki 스킨 메타데이터

/**
* [SkinName] skin
*
* @file
* @ingroup Skins
* @version [#].[#].[#]
* @author [name] ([URL] / [E-Mail])
* @license [URL] [name]
*/
  1. 꺾쇠괄호 안의 모든 것을 스킨에 적합한 것으로 바꾼다.
  2. 그 다음에 SkinTemplate의 서브클래스를 작성하고, 스킨의 이름, 스타일 및 템플리트를 표시하는 initPage 메소드를 오버라이드해야 한다.
  3. SkinName 및 skinname을 스킨의 이름으로 바꾸는 것을 기억하자.

2) 새 스킨을 제공하기 위한 SkinTemplate 확장하기

// inherit main code from SkinTemplate, set the CSS and template filter
class SkinSkinName extends SkinTemplate {
function initPage( OutputPage $out ) {
parent::initPage( $out );
$this->skinname = 'skinname';
$this->stylename = 'skinname';
$this->template = 'SkinNameTemplate';
}
}


  • 스킨에서 가장 열심히 일하는 것은 QuickTemplate 서브클래스일 것이다.

3) 대부분의 작업이 템플릿에서 완료됨

class SkinNameTemplate extends QuickTemplate {
...
/**
* Template filter callback for this skin.
* Takes an associative array of data set from a SkinTemplate-based
* class, and a wrapper for MediaWiki's localization database, and
* outputs a formatted page.
*/
public function execute() {
global $wgUser, $wgSitename;
$skin = $wgUser->getSkin();

// retrieve site name
$this->set( 'sitename', $wgSitename );

// suppress warnings to prevent notices about missing indexes
// in $this->data
wfSuppressWarnings();

/* compose XHTML output */

><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
  1. QuickTemplate 서브클래스 내에서 범주 목록과 원하는 방식의 상호 참조와 같은 것들을 형식화하고 스타일링하는 메소드를 오버라이드할 것이다.
  2. 이 클래스의 execute 메소드는 XHTML 문서로 전체 페이지를 레이아웃하여 페이지 조직과 스타일링 전체의 제어를 제공한다.
  3. 여기에서 XHTML과 CSS 페이지 레이아웃과 스타일링에 들어갈 수는 없으니까 바로 시도해 볼 수 있는 예제를 위해 MediaWiki의 스킨 폴더를 한 번 살펴보자.

1.1.4 특별 페이지 추가하기[편집]

  1. MediaWiki에서 특수 페이지가 시스템 전체의 메시지 텍스트를 편집하고 설치된 확장을 나열하거나 외부 링크의 목록을 받을 수 있는 등 구체적이고 wiki에 유용할 수 있는 작업을 하도록 요청 시 생성된다.
  2. 달리 지정하지 않는 경우에 특수 페이지는 누구나 사용 가능하며 특수 페이지의 Special:SpecialPages 목록에 나타난다.
  3. 또한 특수 페이지를 설정할 수도 있기 때문에 특수:YourPageName 구문을 사용하여 페이지에 인라인을 포함시킬 수 있다.
  4. 다른 확장과 마찬가지로 특수 페이지는 하나의 디렉토리로 확장 폴더에 설치된다. 이는 네 가지 파일로 구성되어 있다.
    1. -specialpage/specialpage.php ― 확장의 설정 파일
    2. -specialpage/specialpage.aliases.php ― 특수 페이지의 이름을 위한 별명
    3. -specialpage/specialpage.body.php ― 특수 페이지의 기본 코드
    4. -specialpage/specialpage.i18n.php ― 특수 페이지의 국제화 문자열
  5. CHStats.php에서 코드는 확장을 위해 대변을 추가하고, 별명, 본문 및 i18n 파일을 등록하며, 필요한 경우에 wiki 엔진에 CHStats 클래스를 자동로드하도록 알려준다.

4) CHStats 특수 페이지 설정하기

<php
# This is not a valid entry point to MediaWiki.
if( !defined( 'MEDIAWIKI' ) ) {
echo <<<EOT
To install CHStats, put the following line in LocalSettings.php:
require_once( "\$IP/extensions/CHStats/CHStats.php" );
EOT;
exit( 1 );
}

# Take credit for this extension.
$wgExtensionCredits['specialpage'][] = array(
'name' => 'CHStats',
'author' => 'Chris Herborth (chrish@pobox.com)',
'url' => 'http://www.pobox.com/~chrish/CHStats/',
'description' => 'A simple special page demonstration, showing some DB stats.',
'descriptionmsg' => 'chstats-desc',
'version' => '1.0.0',
);

$dir = dirname( __FILE__ ) . '/';

# Register the extension's main code/class.
$wgAutoloadClasses['CHStats'] = $dir . 'CHStats.body.php';

# Register our internationalization files.
$wgExtensionMessagesFiles['CHStats'] = $dir . 'CHStats.i18n.php';
$wgExtensionAliasesFiles['CHStats'] = $dir . 'CHStats.aliases.php';

# Let MediaWiki know about the new special page.
$wgSpecialPages['CHStats'] = 'CHStats';

>
  1. CHStats.body.php에서 새 클래스인 CHStats를 작성하는데, 이는 SpecialPage 클래스를 확장한 것이다. 생성자에서 상위 클래스를 초기화한 다음에 wfLoadExtensionMessages를 호출하여 국제화 메시지를 로드한다. 액세스를 # 제한하고 페이지를 숨길 수 있는 SpecialPage 클래스 생성자에 대한 자세한 내용을 보려면 특수 페이지 개발자의 안내서 페이지를 확인한다
  2. execute 메소드의 오버라이드는 페이지를 생성하는 작업을 한다.

5) CHStats 특수 페이지 생성하기

# This is where the special page's output is created.
function execute( $par ) {
global $wgOut;

# Initialize the output page.
$this->setHeaders();

# Do stuff.
$wgOut->addWikiText( "Some stats about this '''Wiki''':" );

$db = wfGetDB( DB_SLAVE );
// SELECT ... FROM site_stats
$result = $db->select( 'site_stats',
array( 'ss_total_views', 'ss_total_edits',
'ss_total_pages', 'ss_users' ) );
$statList = array();
foreach( $result as $row ) {
$statList[] = '* Total page views: ' . $row->ss_total_views;
$statList[] = '* Total page edits: ' . $row->ss_total_edits;
$statList[] = '* Total # of users: ' . $row->ss_users;
}

$wgOut->addWikiText( implode( "\n", $statList ) );

$wgOut->addWikiText( "That's it." );
}
  1. execute 메소드에서 $par 인수는 서브페이지이다.
    1. 예를 들어 Special:CHStats/foo를 로드하면 $par는 foo로 설정될 것이다(분명히 역사적인 특이한 이름이다).
  2. 먼저 페이지 머리글을 설정하기 위해 setHeaders 메소드를 사용한 다음에 결과물 스트림에 일부 마크업을 쓰기 위해 $wgOut->addWikiText를 호출한다.
  3. 형식화된 HTML을 직접 쓰기 위해 $wgOut->addHTML도 사용할 수 있지만 필자는 결과물에서 wiki 마크업을 사용하고 있다.
  4. 이에 대한 자세한 내용과 다른 페이지에서 인라인을 포함시킬 수 있는 특수 페이지로 wiki 마크업 및/또는 HTML을 적절하게 추가하는 방법을 보려면 특수 페이지 개발자의 안내서를 참조한다(참고자료 참조).
  5. CHStats 페이지는 데이터베이스에 대한 참조를 얻기 위해 wfGetDB 함수를 사용한다(읽기 전용 조작을 위해서는 DB_SLAVE를 사용하고, 쓰기 전용 조작을 위해서는 DB_MASTER를 사용함).
  6. 그 다음에 site_stats 데이터베이스로부터 몇 가지 필드를 선택하고 wiki 마크업을 사용하여 글머리 기호 목록으로 결과를 형식화한다.
  7. 이 특수 페이지의 결과물의 모양은 그림 4와 같이 표시될 수 있다.
    https://dataonair.or.kr/publishing/img/knowledge/20101117_44_4.jpg%0A
  8. CHStats.i18n.php에서 찾을 수 있는 국제화 문자열은 지원되는 언어당 항목 한 개의 배열로 구성되어 있다(영어, 프랑스어, 독일어 및 이 경우에는 스페인어).
  9. 각 항목에서 배열 맵핑 문자열 ID는 현지화된 텍스트에 해당되는 것이다.
    1. Google Translate는 프랑스어, 독일어 및 스페인어 비트에 사용되었의 현지화된 버전이 들어있는 유사한 배열이 있다. 이를 통해 프랑스어 사용자(예를 들어)는 Sp?cial:StatsCH로 페이지에 액세스한다.
  • 태그 추가하기
  1. MediaWiki를 확장하는 다른 유명한 방법은 새 XML 태그의 지원을 마크업에 추가하는 것이다.
  2. 이러한 태그는 태그 속성이나 내용에 기반하여 다른 결과물을 제작할 수 있고, 인라인 HTML 또는 심지어 형식화된 결과물의 큰 블록을 삽입하는 데 유용하다.
  3. 태그 확장은 확장 폴더 아래 고유한 디렉토리에 설치되고 이 기사의 시작 부분에 설명했던 세 가지 파일 규칙을 사용한다.
  4. CHUser이라는 이름으로 제작한 간단한 예제를 살펴보자.
    1. -CHUser/CHUser.php ― 확장 설정
    2. -CHUser/CHUser.body.php ― 기본 확장 코드
    3. -CHUser/CHUser.i18n.php ― 국제화 데이터
  5. 비록 $wgHooks 배열을 사용하여 확장의 init 메소드를 ParserFirstCallInit 목록에 추가하고 있다고 하더라도 CHUser.php에서 진행 중인 확장 설정은 이미 본 것과 유사하다.
  6. CHUser::init은 첫 번째 사용될 때 호출될 것이다.

6) 태그 확장 설정하기

# Let MediaWiki know about the new tag.
$wgHooks['ParserFirstCallInit'][] = 'CHUser::init';
  1. CHUser.body.php 내에서 init 메소드는 두 가지 태그인 <chuser>와 <bz>를 등록한다(Listing 7 참조). 이 확장은 하나의 확장에 두 개의 서로 다른 태그를 제공한다.
  2. 원하는 경우 이 기사에서 논의한 모든 확장을 쉽게 결합할 수 있다.
  3. 분리하는 데 필요한 요구사항은 없다(독자 고유의 목표를 제외하고).

7) 태그 등록하기

public static function init( &$parser ) {
# Add our <chuser> tag handler, the continue.
$parser->setHook( 'chuser', 'CHUser::render' );
$parser->setHook( 'bz', 'CHUser::renderBugzilla' );
return true;
}
  1. wiki 마크업 엔진은 <chuser> 태그가 발생할 때마다 CHUser::render 메소드를 호출하고 <bz> 태그는 CHUser::renderBugzilla를 호출할 것이다.
  2. <chuser> 렌더링 메소드는 지정된 사용자의 전체 이름과 이메일 주소를 선택하고 사용자의 전체 이름(있는 경우)을 랩핑하는 mailto: 링크로 이를 형식화한다.

8) 에서 부터 전체 이름 또는 이메일 주소가 데이터베이스에 없는 케이스를 대부분의 논리가 간단하게 핸들링하는 것을 볼 수 있다(예를 들어 필자의 wiki에서 Admin 계정의 경우에 해당).


8) UserName 핸들링하기

public static function render( $input, $args, $parser, $frame ) {
$user = mysql_escape_string( $input );

$db = wfGetDB( DB_SLAVE );
// SELECT ... FROM user
$result = $db->select( 'user',
array( 'user_real_name', 'user_email' ),
'user_name = \'' . $user . '\'' );
$mailtos = array();
foreach( $result as $row ) {
$thisUser = '<span class="user">';

if( $row->user_email ) {
$thisUser = $thisUser . 'user_email ) . '">';
}

if( $row->user_real_name ) {
$thisUser = $thisUser . htmlspecialchars( $row->user_real_name );
} else {
$thisUser = $thisUser . htmlspecialchars( $input );
}

if( $row->user_email ) {
$thisUser = $thisUser . '';
}

$thisUser = $thisUser . '</span>';

$mailtos[] = $thisUser;
}

return implode( ", ", $mailtos );
}
  1. 9) 는 <bz> 태그가 어떻게 그 ID 속성을 사용하여 MediaWiki Bugzilla 데이터베이스에서 지정된 버그 보고서로 링크하는지 보여준다.
  2. 이는 외부 데이터 소스로 작업하는 것이 얼마나 쉬운지 보여준다.
  3. 고급스럽게 수행하려면 Ajax를 사용하여 링크하는 것이 아니라 버그 보고서를 로드하고, 링크 대신에 일부 데이터를 표시할 수 있다.

9) MediaWiki Bugzilla로 링크

public static function renderBugzilla( $input, $args, $parser, $frame ) {
$retval = '';
if( $args['id'] ) {
$bzId = htmlspecialchars( $args['id'] );

$retval = 'MediaWiki Bug #' . $bzId . '';
} else {
$retval = '<span class="error">No bug ID specified</span>';
}

return $retval;
}

그림 5에서 작동 중인 이러한 두 개의 태그를 볼 수 있다. 그림 5. 작동 중인 확장

10) 에서는 페이지의 섹션에 대한 wiki 마크업의 모양을 보여준다.


10) 확장을 시연하는 wiki 마크업

  • Extension testing

20101117_44_5.jpg

If this is working, we should see a timestamp: 틀:CHSTAMP

CHUser info:

  • Admin: <chuser>Admin</chuser>
  • Chrish: <chuser>Chrish</chuser>

<bz id="1024" />

  1. CHUser 확장으로부터 볼 수 있는 것과 같이 사용자 정의 XML 태그의 지원을 추가하는 것은 쉽고 이를 통해 거의 모든 것을 할 수 있다.
  2. 모든 PHP 기능과 MediaWiki 서비스가 사용 가능하므로 데이터를 외부 시스템으로부터 뽑아내고(또는 여기로 데이터를 전송하거나) 현재 사용자의 신임 정보와 권한에 기반하여 작동을 변경하거나 뷰어의 브라우저에서 직접 태스크를 실행하도록 JavaScript를 삽입한다.
  3. 가능성과 무한대는 고유의 특정 필요성과 요구 사항에만 제한을 받는다.


  1. MediaWiki의 확장 규칙 안내
  2. MediaWiki 확장 쓰기에 대한 소개로서 간단한 wiki 변수 확장을 작성하는 방법
  3. MediaWiki의 스킨 기능의 개요는 독자 고유의 사용자 정의된 사이트 레이아웃의 작성을 시작하는 데 유용하다.
  4. 특수 페이지는 데이터베이스이든 다른 소스이든 이로 부터 검색하여 정보를 생성하는 데 사용되기 때문에 시스템의 일부 통계를 표시하는 것을 생성.
  5. 그 다음에 아무 페이지에서나 wiki 마크업에 포함될 수 있는 두 개의 사용자 정의 XML 태그 작성.