Extension:SacredText

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
SacredText

Release status: beta

Implementation Tag, Database
Description Can be used to quote sacred texts, without linking to external websites. Adds the sacred texts to the user's database.
Author(s) JonathanWillifordtalk, Leucostictetalk
Last version 0.0.2
MediaWiki 1.19+
Database changes yes
Schema registration yes
License GPLv3
Download http://sacredtext.googlecode.com/svn/trunk/ ; for code that works, see below
Example http://wiki.mises.org/wiki/Holy_Bible
Parameters

$wgSacredChapterAlias, $wgSacredUseBibleTag

Hooks used
ParserFirstCallInit

LoadExtensionSchemaUpdates

Check usage and version matrix

Contents

What can this extension do? [edit]

Can be used to quote sacred texts, without any links to external websites.

Usage [edit]

One verse [edit]

The code

<bible>Gen 1:5</bible>

will result in:

Gen 1:5 And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day.

The following also has the same result:

<sacredtext text="Christian Bible" ver="kjv">Gen 1:5</sacredtext>

Multiple verses [edit]

The code

<bible>1 Corinthians 4:21-5:1</bible>

will result in:

1 Corinthians 4:21-5:1 What will ye? shall I come unto you with a rod, or in love, and in the spirit of meekness? It is reported commonly that there is fornication among you, and such fornication as is not so much as named among the Gentiles, that one should have his father's wife.

Parser function [edit]

You can also use a parser function; for example:

{{#bible: Genesis 1:1}}

will result in:

Gen 1:5 And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day.

Installation [edit]

Get the Scripture data [edit]

Due to the size of the SQL scripts that add the scriptures to the database, they are kept on a different SVN repository. To download, please execute the following command while inside the SacredText directory:

svn checkout http://sacredtext.googlecode.com/svn/trunk/data data

Or, since there's only one file, just get it from here.

Edit LocalSettings.php [edit]

To install this extension, add the following to LocalSettings.php:

require_once("$IP/extensions/SacredText/SacredText.php");
$wgSacredUseBibleTag = true; // set to false to reserve the bible tag for another extension

Create the database table [edit]

Then run "maintenance/update.php". This will create the database table to hold the verses and add the entries for the King James Version of the Bible.

Configuration parameters [edit]

$wgSacredChapterAlias [edit]

If you want to additional abbreviations for chapters. The first index indicates the religious text where you want to use the abbreviation (ex. "Christian Bible", "Hebrew Bible", "Quran"). Example:

$wgSacredChapterAlias["Christian Bible"]["II Chron"]="2 Chronicles";

$wgSacredUseBibleTag [edit]

Set this to false if you want another extension to be able to use the <bible>...</bible> tags. Defaults to true.

$wgSacredUpdateTable [edit]

Set this to false if you don't want the sacredtext_verses table to be dropped and re-added upon running update.php. E.g., perhaps you already loaded all the verses you needed into it, so you have no need to update it. Defaults to true.

Sacred texts and translations [edit]

Currently, only the King James Version translation of the Christian Bible is added to the database; however other religious texts and translations can be added. I am looking to add more sacred texts and other translations (that are in public domain or have lenient licenses). Please contact me if you are interested in helping.

Changelog [edit]

v0.0.2 [edit]

  • Added parser functions.
  • Added ability to view a range of Bible verses (e.g. Genesis 1:1-1:3).
  • Fixed glitch that prevented verses with double-digit chapters (e.g. Revelation 20:15) from rendering properly.
  • Disabled fallback to BibleGateway.com.
  • Disabled automated reading of data directory; reinstated hard-coded /data/bible_kjv_entire.sql.
  • Added SacredText.i18n.php.
  • Added $wgSacredUpdateTable.

Files [edit]

SacredText.php [edit]

<?php
/**
 * SacredText MediaWiki extension.
 *
 * This extension makes it easy to quote religious scriptures.
 *
 * Written by Jonathan Williford and Leucosticte
 * https://www.mediawiki.org/wiki/User:JonathanWilliford
 * https://www.mediawiki.org/wiki/User:Leucosticte
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 * @ingroup Extensions
 */
 
# Alert the user that this is not a valid entry point to
# MediaWiki if they try to access the special pages file directly.
if (!defined('MEDIAWIKI')) {
        echo <<<EOT
To install my extension, put the following line in LocalSettings.php:
require_once( "\$IP/extensions/SacredText/SacredText.php" );
EOT;
        exit( 1 );
}
 
$wgExtensionCredits['parserhook'][] = array(
        'path' => __FILE__,
        'name' => 'SacredText',
        'author' => '[https://www.mediawiki.org/wiki/User:JonathanWilliford Jonathan Williford], '
                . '[https://www.mediawiki.org/wiki/User:Leucosticte Leucosticte]',
        'description' => 'Makes it easy to quote religious scriptures',
        'descriptionmsg' => 'sacredtext-desc',
        'url' => 'https://www.mediawiki.org/wiki/Extension:SacredText',
        'version' => '0.0.2',
);
 
$dir = dirname(__FILE__) . '/';
$wgAutoloadClasses['SacredTextLookup'] = $dir . 'SacredText.lookup.php';
 
// the following are the parameters that can be set in LocalSettings.php
$wgSacredUseBibleTag = true;
$wgSacredUpdateTable = true; // Drop and create new table when update.php is run
$wgSacredChapterAlias = array();
$wgSacredChapterAlias["Christian Bible"] = array();
$wgSacredChapterAlias["Christian Bible"]["1Chronicles"]="1 Chronicles";
$wgSacredChapterAlias["Christian Bible"]["1Corinthians"]="1 Corinthians";
$wgSacredChapterAlias["Christian Bible"]["1John"]="1 John";
$wgSacredChapterAlias["Christian Bible"]["1Kings"]="1 Kings";
$wgSacredChapterAlias["Christian Bible"]["1Peter"]="1 Peter";
$wgSacredChapterAlias["Christian Bible"]["1Samuel"]="1 Samuel";
$wgSacredChapterAlias["Christian Bible"]["1Thessalonians"]="1 Thessalonians";
$wgSacredChapterAlias["Christian Bible"]["1Timothy"]="1 Timothy";
$wgSacredChapterAlias["Christian Bible"]["2Chronicles"]="2 Chronicles";
$wgSacredChapterAlias["Christian Bible"]["2Corinthians"]="2 Corinthians";
$wgSacredChapterAlias["Christian Bible"]["2John"]="2 John";
$wgSacredChapterAlias["Christian Bible"]["2Kings"]="2 Kings";
$wgSacredChapterAlias["Christian Bible"]["2Peter"]="2 Peter";
$wgSacredChapterAlias["Christian Bible"]["2Samuel"]="2 Samuel";
$wgSacredChapterAlias["Christian Bible"]["2Thessalonians"]="2 Thessalonians";
$wgSacredChapterAlias["Christian Bible"]["2Timothy"]="2 Timothy";
$wgSacredChapterAlias["Christian Bible"]["3John"]="3 John";
$wgSacredChapterAlias["Christian Bible"]["1Ch"]="1 Chronicles";
$wgSacredChapterAlias["Christian Bible"]["1Co"]="1 Corinthians";
$wgSacredChapterAlias["Christian Bible"]["1Jo"]="1 John";
$wgSacredChapterAlias["Christian Bible"]["1Ki"]="1 Kings";
$wgSacredChapterAlias["Christian Bible"]["1Pe"]="1 Peter";
$wgSacredChapterAlias["Christian Bible"]["1Sa"]="1 Samuel";
$wgSacredChapterAlias["Christian Bible"]["1Th"]="1 Thessalonians";
$wgSacredChapterAlias["Christian Bible"]["1Ti"]="1 Timothy";
$wgSacredChapterAlias["Christian Bible"]["2Ch"]="2 Chronicles";
$wgSacredChapterAlias["Christian Bible"]["2Co"]="2 Corinthians";
$wgSacredChapterAlias["Christian Bible"]["2Jo"]="2 John";
$wgSacredChapterAlias["Christian Bible"]["2Ki"]="2 Kings";
$wgSacredChapterAlias["Christian Bible"]["2Pe"]="2 Peter";
$wgSacredChapterAlias["Christian Bible"]["2Sa"]="2 Samuel";
$wgSacredChapterAlias["Christian Bible"]["2Th"]="2 Thessalonians";
$wgSacredChapterAlias["Christian Bible"]["2Ti"]="2 Timothy";
$wgSacredChapterAlias["Christian Bible"]["3Jo"]="3 John";
$wgSacredChapterAlias["Christian Bible"]["Act"]="Acts";
$wgSacredChapterAlias["Christian Bible"]["Amo"]="Amos";
$wgSacredChapterAlias["Christian Bible"]["Col"]="Colossians";
$wgSacredChapterAlias["Christian Bible"]["Dan"]="Daniel";
$wgSacredChapterAlias["Christian Bible"]["Deu"]="Deuteronomy";
$wgSacredChapterAlias["Christian Bible"]["Ecc"]="Ecclesiastes";
$wgSacredChapterAlias["Christian Bible"]["Eph"]="Ephesians";
$wgSacredChapterAlias["Christian Bible"]["Est"]="Esther";
$wgSacredChapterAlias["Christian Bible"]["Exo"]="Exodus";
$wgSacredChapterAlias["Christian Bible"]["Eze"]="Ezekial";
$wgSacredChapterAlias["Christian Bible"]["Ezr"]="Ezra";
$wgSacredChapterAlias["Christian Bible"]["Gal"]="Galatians";
$wgSacredChapterAlias["Christian Bible"]["Gen"]="Genesis";
$wgSacredChapterAlias["Christian Bible"]["Ge"]="Genesis";
$wgSacredChapterAlias["Christian Bible"]["Hab"]="Habakkuk";
$wgSacredChapterAlias["Christian Bible"]["Hag"]="Haggai";
$wgSacredChapterAlias["Christian Bible"]["Heb"]="Hebrews";
$wgSacredChapterAlias["Christian Bible"]["Hos"]="Hosea";
$wgSacredChapterAlias["Christian Bible"]["Isa"]="Isaiah";
$wgSacredChapterAlias["Christian Bible"]["Jam"]="James";
$wgSacredChapterAlias["Christian Bible"]["Jer"]="Jeremiah";
$wgSacredChapterAlias["Christian Bible"]["Job"]="Job";
$wgSacredChapterAlias["Christian Bible"]["Joe"]="Joel";
$wgSacredChapterAlias["Christian Bible"]["Joh"]="John";
$wgSacredChapterAlias["Christian Bible"]["Jon"]="Jonah";
$wgSacredChapterAlias["Christian Bible"]["Jos"]="Joshua";
$wgSacredChapterAlias["Christian Bible"]["Jud"]="Jude";
$wgSacredChapterAlias["Christian Bible"]["Jud"]="Judges";
$wgSacredChapterAlias["Christian Bible"]["Lam"]="Lamentations";
$wgSacredChapterAlias["Christian Bible"]["Lev"]="Leviticus";
$wgSacredChapterAlias["Christian Bible"]["Luk"]="Luke";
$wgSacredChapterAlias["Christian Bible"]["Mal"]="Malachi";
$wgSacredChapterAlias["Christian Bible"]["Mar"]="Mark";
$wgSacredChapterAlias["Christian Bible"]["Mat"]="Matthew";
$wgSacredChapterAlias["Christian Bible"]["Mic"]="Micah";
$wgSacredChapterAlias["Christian Bible"]["Nah"]="Nahum";
$wgSacredChapterAlias["Christian Bible"]["Neh"]="Nehemiah";
$wgSacredChapterAlias["Christian Bible"]["Num"]="Numbers";
$wgSacredChapterAlias["Christian Bible"]["Oba"]="Obad";
$wgSacredChapterAlias["Christian Bible"]["Phi"]="Philemon";
$wgSacredChapterAlias["Christian Bible"]["Phi"]="Philippians";
$wgSacredChapterAlias["Christian Bible"]["Pro"]="Proverbs";
$wgSacredChapterAlias["Christian Bible"]["Psa"]="Psalms";
$wgSacredChapterAlias["Christian Bible"]["Psalm"]="Psalms";
$wgSacredChapterAlias["Christian Bible"]["Rev"]="Revelation";
$wgSacredChapterAlias["Christian Bible"]["Rom"]="Romans";
$wgSacredChapterAlias["Christian Bible"]["Rut"]="Ruth";
$wgSacredChapterAlias["Christian Bible"]["Son"]="Song of Solomon";
$wgSacredChapterAlias["Christian Bible"]["Song"]="Song of Solomon";
$wgSacredChapterAlias["Christian Bible"]["SSol"]="Song of Solomon";
$wgSacredChapterAlias["Christian Bible"]["Tit"]="Titus";
$wgSacredChapterAlias["Christian Bible"]["Zec"]="Zechariah";
$wgSacredChapterAlias["Christian Bible"]["Zep"]="Zephaniah";
 
$wgHooks['ParserFirstCallInit'][] = 'efSacredTextParserInit';
$wgHooks['LoadExtensionSchemaUpdates'][] = 'updateSacredTextDB';
$wgExtensionMessagesFiles['SacredText'] = __DIR__ . '/SacredText.i18n.php';
 
function efSacredTextParserInit( $parser ) {
        global $wgSacredUseBibleTag;
        $parser->setHook( 'sacredtext', 'SacredTextLookup::hookSacredText' );
        $parser->setFunctionHook( 'sacredtext', 'SacredTextLookup::parserFunctionHookSacredText' );
        if( $wgSacredUseBibleTag ) {
                $parser->setHook( 'bible', 'SacredTextLookup::hookBible' );
                $parser->setFunctionHook( 'bible', 'SacredTextLookup::parserFunctionHookBible' );
        }
        return true;
}
 
function updateSacredTextDB() {
        global $wgExtNewTables, $wgSacredUpdateTable;
        // Abort schema update if the config setting says so; this is, e.g., in case you feel no
        // need to drop that table and create it again
        if ( !$wgSacredUpdateTable ) {
                return true;
        }
        $wgExtNewTables[] = array(
                'sacredtext_verses1',
                dirname( __FILE__ ) . '/SacredText.verses.sql' );
        /*$dir = dirname( __FILE__ ) . '/data/';
        while( $file = readdir( $dir ) )
        {
                if($file == '.' && $file == '..') continue; 
                if(!is_file($dir.$file)) continue;
                if(!preg_match('^(.*)\.sql$', $file, $matches)) continue; 
                $wgExtNewTables[] = array(
                        $matches[1],
                        $dir.$file);
        }*/
 
        $wgExtNewTables[] = array(
                'sacredtext_verses_kjv_entire',
                dirname( __FILE__ ) . '/data/bible_kjv_entire.sql' );
        return true;
}

SacredText.lookup.php [edit]

<?php
# Alert the user that this is not a valid entry point to
# MediaWiki if they try to access the special pages file directly.
if (!defined('MEDIAWIKI')) {
        echo <<<EOT
To install my extension, put the following line in LocalSettings.php:
require_once( "\$IP/extensions/SacredText/SacredText.setup.php" );
EOT;
        exit( 1 );
}
 
class SacredTextLookup {
 
        public static function parseInput( $input, &$book, &$chapternum, &$versenums,
                &$secondChapterNum = '', &$secondVerseNum = '' ) {
                if( preg_match( "/^\s*([\s\w]*\w+)\s*(\d+):(\d+)/", $input, $matches) ) {
                $book = $matches[1];
                $chapternum = $matches[2];
                $versenums = array();
                $versenums[] = $matches[3];
                // Hack to fix problem with regex putting, e.g. "Revelation 2 0:15"
                // instead of "Revelation 20:15"
                while ( is_numeric ( $book[ strlen ( $book ) - 1] ) ) {
                        // Add a number to the beginning of $chapter
                        $chapternum = substr ( $book , strlen ( $book ) - 1 ) . $chapternum;
                        // Chop one character off the end of $book
                        $book = substr ( $book, 0, strlen ( $book ) - 1 );
                }
                $book = trim ( $book );
                // Get the second verse, e.g. verse 14 in 1 Peter 2:13-14
                $secondChapterNum = $chapternum;
                $secondVerseNum = $versenums[0];
                $dashExploded = explode ( '-', $input );
                if ( count ( $dashExploded ) === 2 ) {
                        $colonExploded = explode ( ':', $dashExploded[ 1 ] );
                        if ( count ( $colonExploded ) > 2
                                || ! is_numeric ( $colonExploded[ 0 ] )
                                || ( isset ( $colonExploded[ 1 ] )
                                        && ! is_numeric ( $colonExploded[ 1 ] ) )
                                ) {
                                return true;
                        }
                        if ( count ( $colonExploded ) === 2 ) {
                                $secondChapterNum = $colonExploded [ 0 ];
                                $secondVerseNum = $colonExploded [ 1 ];
                        } else {
                                $secondVerseNum = $colonExploded [ 0 ];
                        }
                        // Bail if, e.g., 1 Peter 2:14-13 is put
                        if ( $secondChapterNum < $chapternum
                                || ( $secondChapterNum == $chapternum
                                        && $secondVerseNum < $versenums[0] ) ) {
                                $secondChapterNum = $chapternum;
                                $secondVerseNum = $versenums[0];
                        }
                }
                return true;
            } else {
                return false;
            }
        }
 
        public static function hookBible( $input, $args, $parser, $frame ) {
                if( self::parseInput( $input, $book, $chapternum, $versenums,
                        $secondChapterNum, $secondVerseNum ) ) {
                        $lang = "en";
                        $ver = "kjv";
                        if( array_key_exists("lang", $args) ) $lang = $args["lang"];
                        if( array_key_exists("ver", $args) ) $ver = $args["ver"];
                        return htmlspecialchars( $input ) ." ". self::lookup( "Christian Bible",
                                $book,$chapternum, $versenums, $lang, $ver, $secondChapterNum,
                                $secondVerseNum );
                } else {
                        return htmlspecialchars( $input .
                                " Could not parse reference.  Please use the format 'Gen 1:10'." );
                }
        }
 
        public static function hookSacredText( $input, $args, $parser, $frame ) {
                if( self::parseInput( $input, $book, $chapternum, $versenums,
                        $secondChapterNum, $secondVerseNum ) ) {
                $lang = "en";
                $ver = "kjv";
                $religtext = "Christian Bible";
                if( array_key_exists("lang", $args) ) $lang = $args["lang"];
                if( array_key_exists("ver", $args) ) $ver = $args["ver"];
                if( array_key_exists("text", $args) ) $religtext = $args["text"];
 
                return htmlspecialchars( $input ) ." ". self::lookup( $religtext, $book,
                        $chapternum, $versenums, $lang, $ver, $secondChapterNum, $secondVerseNum );
            } else {
                return htmlspecialchars( $input . " Could not parse reference. '
                        . 'Please use the format 'Gen 1:10'." );
            }
        }
 
        public static function parserFunctionSacredText ( $parser, $param1 = '' ) {
                return self::hookSacredText ( $param1, array(), $parser, array() );
        }
 
        public static function parserFunctionHookBible ( $parser, $param1 = '' ) {
                return self::hookBible ( $param1, array(), $parser, array() );
        }
 
        public static function lookup( $religtext, $book, $chapternum, $versenums, $lang, $ver,
                $secondChapterNum, $secondVerseNum ) {
            global $wgSacredChapterAlias, $wgDBPrefix;
            $dbr = wfGetDB( DB_SLAVE );
 
            if( array_key_exists($religtext, $wgSacredChapterAlias) &&
                array_key_exists($book, $wgSacredChapterAlias[$religtext] ) )
            {
                $book = $wgSacredChapterAlias[$religtext][$book];
            }
 
            if( strcasecmp($religtext,"Christian Bible")==0 ) {
                if( strcasecmp($ver,"AV")==0 ) {
                    $ver = "KJV";
                }
            }
 
            if ( $chapternum == $secondChapterNum ) {
                $where = array ( "{$wgDBPrefix}st_chapter_num=$chapternum
                        AND {$wgDBPrefix}st_verse_num>=$versenums[0]
                        AND {$wgDBPrefix}st_verse_num<=$secondVerseNum" );
            } else {
                $whereClause = "(({$wgDBPrefix}st_chapter_num=$chapternum
                        AND {$wgDBPrefix}st_verse_num>=$versenums[0])
                        OR  ({$wgDBPrefix}st_chapter_num=$secondChapterNum
                        AND {$wgDBPrefix}st_verse_num<=$secondVerseNum)";
                $chapterArray = range ( $chapternum, $secondChapterNum );
                foreach ( $chapterArray as $thisChapter ) {
                        if ( $thisChapter != $chapternum && $thisChapter != $secondChapterNum ) {
                                $whereClause .= " OR {$wgDBPrefix}st_chapter_num=$thisChapter";
                        }
                }
                $whereClause .= ')';
                $where = array ( $whereClause );
            }
            $where = array_merge ( $where, array(
                    "st_religious_text" => $religtext,
                    "st_book"           => $book,
                    "st_translation"    =>$ver,
                    "st_language"       =>$lang
                ) );
            $obj = $dbr->select( "sacredtext_verses", array("st_text"), $where );
            if( $obj ) {
                $returnText = '';
                $keepGoing = true;
                $firstOne = true;
                while ( $keepGoing === true ) {
                        $row = $obj->fetchRow();
                        if ( $row ) {
                                if ( $firstOne !== true ) {
                                        $returnText .= ' ';
                                }
                                $firstOne = false;
                                $returnText .= $row['st_text'];
                        } else {
                                $keepGoing = false;
                        }
                }
                return htmlspecialchars( $returnText );
            } else {
                        #$r = self::fallback( $religtext, $book, $chapternum, $versenums, $lang, $ver );
                        #if( $r ) return htmlspecialchars( $r );
                        
                return htmlspecialchars( "Could not find: ". $book ." ".$chapternum.":".$versenums[0]
                        ." in the ". $religtext );
        }
        }
 
        public static function fallback( $religtext, $book, $chapternum, $versenums, $lang, $ver ) 
        {
                global $wgSacredFallbackServers;
                if ( !$wgSacredFallbackServers ) {
                        $wgSacredFallbackServers = array();
                }
            if( array_key_exists($religtext, $wgSacredFallbackServers) ) {
                if( array_key_exists($lang, $wgSacredFallbackServers[$religtext]) ) {
                        if( array_key_exists($ver, $wgSacredFallbackServers[$religtext][$lang]) ) {
                                        $url = $wgSacredFallbackServers[$religtext][$lang][$ver]["url"];
                                        $regex = $wgSacredFallbackServers[$religtext][$lang][$ver]["pattern"];
                                }
                        }
                }
                if( strcmp($religtext,"Christian Bible")==0 )
                {
                        $versenum = $versenums[0];
                        $h = fopen("http://www.biblegateway.com/passage/?search=$book%20$chapternum:$versenum&version=$ver",'r' );
                        $str='';
                        $length = 8192;
                        while(!feof($h)) $str.=fread($h,$length);
                        fclose($h);
                        $num = preg_match_all( '/<\/sup>\s*([^<]+)\s*/',$str, $matches, PREG_PATTERN_ORDER );
                        if( $num ) {
                                return implode( " ", $matches[1] );
                        }
                        else return false;
                } 
                return false;
        }
}

SacredText.i18n.php [edit]

<?php
/**
 * Internationalization file.
 */
 
$magicWords = array();
$messages = array();
 
$magicWords['en'] = array(
   'bible' => array( 0, 'bible' ),
   'sacredtext' => array( 0, 'sacredtext' ),
);
 
$messages['en'] = array(
        'sacredtext-desc' => "Makes it easy to quote religious scriptures",
);

SacredText.verses.sql [edit]

-- 
-- SQL for SacredText Extension
-- 
-- Table for SacredText verses
DROP TABLE IF EXISTS /*_*/sacredtext_verses;
CREATE TABLE /*_*/sacredtext_verses (
    -- Primary key
    st_verse_index int(11) NOT NULL auto_increment,
    -- Religious text
    st_religious_text ENUM('Christian Bible', 'Hebrew Bible', 'Quran') NOT NULL default 'Christian Bible',
    -- Book (ex. John)
    st_book VARCHAR(255) NOT NULL,
    -- Chapter
    st_chapter_num SMALLINT NOT NULL,
    -- Verse
    st_verse_num SMALLINT NOT NULL,
    -- Language
    st_language CHAR(2) default 'en' COLLATE utf8_unicode_ci NOT NULL,
    -- Translation
    st_translation VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL,
    -- Actual text
    st_text TEXT character set utf8 collate utf8_unicode_ci NOT NULL,
    PRIMARY KEY (`st_verse_index`)
) /*$wgDBTableOptions*/;

See also [edit]