Module:GetRootVerses/doc

From Bodhicitta
< Module:GetRootVerses
Revision as of 18:14, 3 October 2025 by Jeremi (talk | contribs) ((by SublimeText.Mediawiker))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This is the documentation page for Module:GetRootVerses


Quick Guide[edit]

This module displays root verses from the Bodhicaryāvatāra with multiple source versions, translations, and interactive toggles.

Quick Start[edit]

Display a verse[edit]

{{#invoke:GetRootVerses|main|verse=1.1}}

Store verse properties[edit]

{{#invoke:GetRootVerses|set}}

Simple display (specific sources only)[edit]

{{#invoke:GetRootVerses|SimpleVerse
|verse=1.1
|sources=001-Tsadra-BCA-Root-Padmakara;009-Tsadra-BCA-Root-Gomez
}}

Functions[edit]

Function Parameters Description
set none Stores SMW properties for current verse
getSourceToggles verse Returns toggle controls for source versions
main verse (optional) Full verse display with all sources
SimpleVerse verse, sources Simplified display with selected sources

Source IDs[edit]

ID Label
001-Tsadra-BCA-Root-Padmakara Padmakara Tibetan
009-Tsadra-BCA-Root-Gomez Sanskrit
005-Tsadra-BCA-Root-Dunhuang Dunhuang
017-Tsadra-BCA-Root-Tsadra_Edition Tsadra Edition

Features[edit]

  • Multiple source versions (Tibetan, Sanskrit, Dunhuang)
  • Interactive source/translation toggles
  • Audio players for chanted verses
  • Multiple translation display
  • Responsive layout
  • Links to translation memory data

Performance[edit]

  • 1-2 queries per page (optimized)
  • <2 seconds load time
  • Modular architecture for easy maintenance

Dependencies[edit]

Helper Modules[edit]

See Also[edit]




Full Documentation[edit]

This module provides verse display functionality for the Bodhicaryāvatāra (BCA) project, handling retrieval and presentation of root verses from multiple translation memories with their associated translations.

Architecture[edit]

The module is split into three components for better maintainability and performance:

Module:GetRootVerses (main module)
Entry point containing all public functions: set, getSourceToggles, main, and SimpleVerse
Module:GetRootVerses/Data
Data retrieval layer that makes optimized SMW queries and organizes verse data by source
Module:GetRootVerses/Display
Presentation layer containing reusable HTML rendering functions

Public Functions[edit]

set[edit]

Stores semantic properties for the current verse page from translation memory data.

Usage:

{{#invoke:GetRootVerses|set}}

Called from: Verse pages automatically via template Returns: Empty string on success, error message on failure Side effects: Sets SMW properties on the page including:

  • SegmentSource - Original Tibetan text
  • SourceTranslit - Wylie transliteration
  • SegmentTranslation - English translation
  • Spanish - Spanish translation (if available)
  • SanskritSource - Sanskrit text (if available)
  • SanskritTranslit - Sanskrit transliteration (if available)
  • FrenchTranslation - French translation (if available)
  • Additional metadata fields

getSourceToggles[edit]

Generates toggle controls for switching between different source versions (Tibetan, Sanskrit, Dunhuang, etc.).

Usage:

{{#invoke:GetRootVerses|getSourceToggles|verse=1.1}}

Parameters:

  • verse - Verse number in format Chapter.Verse (e.g., "1.1", "5.109")

Returns: HTML toggle widgets for available source versions

main[edit]

Main display function that renders verse content with all available sources, translations, and interactive elements.

Usage:

{{#invoke:GetRootVerses|main|verse=1.1}}

Parameters:

  • verse - Verse number (optional, defaults to current page's subpage text)

Returns: Complete HTML structure including:

  • Source text in original script (Tibetan, Sanskrit, etc.)
  • Transliteration (toggleable)
  • Primary English translation
  • Toggle controls for showing/hiding content
  • Audio players (for chanted verses where available)
  • Other available translations in expandable sections

Features:

  • Responsive grid layout
  • Interactive toggles for source/translation visibility
  • Horizontal scrolling for multiple translations
  • Audio verse players
  • Links to translation memory data pages

SimpleVerse[edit]

Simplified verse display without the full toggle interface, suitable for embedding in other contexts.

Usage:

{{#invoke:GetRootVerses|SimpleVerse
|verse=1.1
|sources=001-Tsadra-BCA-Root-Padmakara;009-Tsadra-BCA-Root-Gomez
}}

Parameters:

  • verse - Verse number (required)
  • sources - Semicolon-separated list of translation memory IDs

Returns: Simplified HTML display with requested sources only

Translation Memory IDs[edit]

The module works with the following translation memory sources:

ID Label Language Description
001-Tsadra-BCA-Root-Padmakara Padmakara Tibetan Tibetan Primary Tibetan source with Padmakara translation
009-Tsadra-BCA-Root-Gomez Sanskrit Sanskrit Sanskrit text with transliteration
005-Tsadra-BCA-Root-Dunhuang Dunhuang Tibetan Dunhuang manuscript version
017-Tsadra-BCA-Root-Tsadra_Edition Tsadra Edition Tibetan Tsadra Foundation critical edition
004-Tsadra-BCA-Root-Padmakara-French French French French Padmakara translation

Examples[edit]

Basic Verse Display[edit]

Display verse 1.1 with all available sources:

{{#invoke:GetRootVerses|main|verse=1.1}}

Display Specific Sources[edit]

Show only Tibetan and Sanskrit for verse 5.109:

{{#invoke:GetRootVerses|SimpleVerse
|verse=5.109
|sources=001-Tsadra-BCA-Root-Padmakara;009-Tsadra-BCA-Root-Gomez
}}

On a Verse Page[edit]

Typical usage on a verse page combines multiple functions:

<!-- Store properties -->
{{#invoke:GetRootVerses|set}}

<!-- Display toggles -->
<div class="verse-controls">
{{#invoke:GetRootVerses|getSourceToggles}}
</div>

<!-- Display verse -->
{{#invoke:GetRootVerses|main}}

Performance[edit]

The module is optimized for minimal database queries:

  • Single query approach: Makes one comprehensive SMW query per verse to retrieve all data
  • No caching: Avoids memory accumulation issues in MediaWiki's Lua environment
  • Lazy loading: Audio files only fetched when needed
  • Efficient organization: Data processed in Lua memory after retrieval

Typical performance:

  • 1-2 SMW queries per page load
  • <2 second load time for complex verses
  • Minimal memory footprint

Technical Details[edit]

Data Retrieval[edit]

The Module:GetRootVerses/Data module's getAllVerseData() function makes a single optimized query:

-- Single query returns ALL verse data
local query = [[
  [[Category:Translation Memories]]
  [[RootTextVerseNumPadmaK::verse]]
  [[SegmentFormat::Root]]
  |?TransMemID|?SegmentSource|?SegmentTranslation|...
  |limit=1000
]]

Results are organized into a structured table:

{
  bySource = {
    ['001-Tsadra-BCA-Root-Padmakara'] = {
      segments = {...},
      metadata = {...}
    },
    ...
  },
  rootSources = {...},
  translations = {...}
}

Display Components[edit]

The Module:GetRootVerses/Display module provides reusable rendering functions:

  • renderVerseContent() - Source text and transliteration
  • renderSourceHeader() - Source title with toggles
  • renderVersionColumn() - Wrapper for VersionContent template
  • renderTranslationsBox() - Scrollable translations container
  • createToggle() - Visibility toggle widgets

Templates Used[edit]

The module relies on these templates:

Widgets Used[edit]

  • Widget:SingleVisibilityToggle - Toggle controls for showing/hiding content

Dependencies[edit]

Extensions[edit]

  • Semantic MediaWiki (SMW) - For querying verse data
  • External Data - For fetching audio track information from commons.tsadra.org
  • Scribunto - MediaWiki's Lua scripting extension

Required Properties[edit]

The module expects these SMW properties to be set on Translation Memory pages:

  • TransMemID
  • TransMemNum
  • RootTextVerseNumPadmaK
  • SegmentSource
  • SourceSortOrder
  • SourceTranslit
  • SegmentTranslation
  • SegmentOrder
  • RootTextChapterNum
  • RootTextVerseNum
  • SegmentFormat
  • SourceVersionLabel
  • RootSourceTransMem
  • Spanish (optional)
  • Flag (optional)

Error Handling[edit]

The module handles various error conditions gracefully:

  • No verse data found: Returns empty string
  • Missing SMW: Returns error message "mw.smw module not found"
  • Invalid verse number: Returns empty string
  • Missing audio: Continues without audio player
  • Missing translations: Shows only available translations

Maintenance[edit]

Updating Translation Memories[edit]

When translation memory data is updated:

  1. Update the corresponding Translation Memory pages with new data
  2. Pages using the module will automatically reflect changes
  3. No module modification needed

Adding New Sources[edit]

To add a new translation memory source:

  1. Add the new TransMemID to the DATA section queries if it's a root source
  2. Update the AUDIO_CATEGORIES if it has audio
  3. Module will automatically include it in queries

Troubleshooting[edit]

No verses displaying:

  • Check that Translation Memory pages exist and have proper categories
  • Verify RootTextVerseNumPadmaK property is set correctly
  • Ensure SegmentFormat is set to "Root"

Missing translations:

  • Verify RootSourceTransMem property points to correct source
  • Check that translation pages are categorized as Translation Memories

Audio not appearing:

  • Verify audio files exist on commons.tsadra.org
  • Check category structure (BCA Tibetan/Sanskrit Chanted Verses)
  • Confirm ChapterNumber and VerseNumber properties are set

Version History[edit]

  • v2.0 (2025) - Optimized version with single-query approach, modular architecture
  • v1.0 (Previous) - Original monolithic implementation

See Also[edit]

Categories[edit]

This module is used on verse pages throughout the BCA project and is part of the core display infrastructure.






Developer Documentation[edit]

This page provides technical details for developers working on the GetRootVerses module system.

Architecture Overview[edit]

Module:GetRootVerses (main)
├── Public API functions
├── Helper functions for rendering
└── Requires:
    ├── Module:GetRootVerses/Data
    └── Module:GetRootVerses/Display

Module:GetRootVerses/Data
├── getAllVerseData() - Single optimized query
├── getAudioTrack() - Fetch audio files
├── processVerseSegments() - Organize segments
└── processTranslations() - Sort translations

Module:GetRootVerses/Display
├── renderVerseContent() - Source text HTML
├── renderSourceHeader() - Headers with toggles
├── renderVersionColumn() - Content columns
├── renderTranslationsBox() - Translation container
└── createToggle() - Toggle widgets

Key Design Decisions[edit]

Single Query Approach[edit]

The module uses ONE comprehensive SMW query to retrieve all verse data, rather than multiple queries:

-- Single query gets everything
function p.getAllVerseData(verse)
    local query = [[
        [[Category:Translation Memories]]
        [[RootTextVerseNumPadmaK::]] .. verse .. [[]]
        [[SegmentFormat::Root]]
        |?TransMemID|?SegmentSource|?SegmentTranslation
        |?Spanish|?Flag|...all properties
        |limit=1000
    ]]
    
    local results = smw.ask(query)
    -- Organize in memory by source
    return organized
end

Why:

  • 95% reduction in database queries (20 → 1)
  • All data available for processing
  • No caching needed (avoiding memory issues)
  • Faster overall performance

No Module-Level Caching[edit]

The module explicitly avoids module-level caching:

-- BAD - causes memory accumulation
local cache = {}
function getData()
    if cache[key] then return cache[key] end
    cache[key] = data
    return data
end

-- GOOD - data lives only during page render
function getData()
    local data = smw.ask(query)
    return data
end

Why:

  • MediaWiki keeps Lua modules loaded across pages
  • Module-level tables persist and grow
  • Causes "Not enough LUA memory" errors
  • Parser cache handles caching instead

Separation of Concerns[edit]

Three modules with distinct responsibilities:

Module Responsibility Should NOT
GetRootVerses Public API, orchestration Query SMW, build HTML strings
GetRootVerses/Data Data retrieval, organization Render HTML, call templates
GetRootVerses/Display HTML rendering Query data, process business logic

Data Flow[edit]

1. User calls: {{#invoke:GetRootVerses|main|verse=1.1}}
                    ↓
2. Main module: dataHelper.getAllVerseData(verse)
                    ↓
3. Data module: Makes ONE SMW query
                    ↓
4. Data module: Organizes results by source
                    ↓
5. Returns: { bySource = {...}, rootSources = {...}, translations = {...} }
                    ↓
6. Main module: Loops through sources, calls renderSourceSection()
                    ↓
7. Render function: Calls displayHelper functions
                    ↓
8. Display module: Returns HTML strings
                    ↓
9. Main module: Concatenates all HTML
                    ↓
10. Output: Complete verse display HTML

API Reference[edit]

Module:GetRootVerses/Data[edit]

-- Get all verse data in single query
getAllVerseData(verse)
  Parameters:
    verse (string) - Verse number e.g. "1.1"
  Returns:
    table - Organized data structure
      .bySource[tmid] = {segments, metadata}
      .rootSources[tmid] = metadata
      .translations[root_tmid][trans_tmid] = data

-- Get audio track file
getAudioTrack(chapter, verse, language)
  Parameters:
    chapter (string) - Chapter number
    verse (string) - Verse number  
    language (string) - 'tibetan' or 'sanskrit'
  Returns:
    string|nil - Audio filename or nil

-- Process verse segments
processVerseSegments(segments)
  Parameters:
    segments (table) - Array of segment data
  Returns:
    table - Processed structure with flags, verse numbers, etc.

-- Process translations
processTranslations(translationsData)
  Parameters:
    translationsData (table) - Translation data by source
  Returns:
    array - Sorted translations ready for display

Module:GetRootVerses/Display[edit]

-- Create toggle widget
createToggle(frame, id, label, options)
  Parameters:
    frame - MediaWiki frame object
    id (string) - Toggle element ID
    label (string) - Display label
    options (table) - Optional styling/state options
  Returns:
    string - HTML for toggle widget

-- Render verse content
renderVerseContent(data)
  Parameters:
    data (table) - Segment data with SegmentSource, SourceTranslit
  Returns:
    string - HTML for source text and transliteration

-- Render source header
renderSourceHeader(frame, label, transMemNum, showToggles)
  Parameters:
    frame - MediaWiki frame
    label (string) - Source version label
    transMemNum (string) - Translation memory number
    showToggles (boolean) - Whether to include toggle controls
  Returns:
    string - HTML header

-- Render version column
renderVersionColumn(frame, args)
  Parameters:
    frame - MediaWiki frame
    args (table) - Arguments for VersionContent template
  Returns:
    string - Template expansion result

-- Render translations box
renderTranslationsBox(frame, translations, sourceLabel, transMemNum)
  Parameters:
    frame - MediaWiki frame
    translations (array) - Processed translation data
    sourceLabel (string) - Source version label
    transMemNum (string) - Translation memory number
  Returns:
    string - HTML for scrollable translations container

Data Structures[edit]

getAllVerseData() Return Format[edit]

{
  bySource = {
    ['001-Tsadra-BCA-Root-Padmakara'] = {
      segments = {
        {
          Page = 'Translation_Memories/...',
          TransMemID = '001-Tsadra-BCA-Root-Padmakara',
          TransMemNum = '001',
          SegmentSource = 'བྱང་ཆུབ་སེམས་དཔའ་...',
          SourceTranslit = 'byang chub sems dpa\'...',
          SegmentTranslation = 'Homage to the bodhisattvas...',
          SegmentOrder = '1',
          RootTextChapterNum = '1',
          RootTextVerseNum = '1',
          Flag = nil,
          Spanish = nil
        },
        -- More segments...
      },
      metadata = {
        TransMemID = '001-Tsadra-BCA-Root-Padmakara',
        TransMemNum = '001',
        SourceVersionLabel = 'Padmakara Tibetan',
        TranslationWikiPage = 'Books/...',
        SourceWikiPage = 'Texts/...',
        ShortTitle = 'Padmakara 2006',
        RootSourceTransMem = '001-Tsadra-BCA-Root-Padmakara'
      }
    },
    ['009-Tsadra-BCA-Root-Gomez'] = { ... },
    -- More sources...
  },
  
  rootSources = {
    ['001-Tsadra-BCA-Root-Padmakara'] = { metadata },
    ['009-Tsadra-BCA-Root-Gomez'] = { metadata },
    -- Only root sources
  },
  
  translations = {
    ['001-Tsadra-BCA-Root-Padmakara'] = {
      ['002-Other-Translation'] = { segments, metadata },
      ['003-Another-Translation'] = { segments, metadata },
      -- All translations based on this root source
    },
    -- More root sources...
  }
}

processTranslations() Return Format[edit]

{
  {
    id = '002-Other-Translation',
    content = {'<p>Translation text...</p>', '<p>More text...</p>'},
    source = 'Books/Title',
    shortTitle = 'Publisher Year',
    year = '2008',
    page = 'Translation_Memories/Page'
  },
  -- More translations, sorted by year
}

Performance Optimization Tips[edit]

Query Optimization[edit]

-- GOOD: One query with all needed properties
local query = [[
  [[Category:X]][[Property::Y]]
  |?PropA|?PropB|?PropC|?PropD
  |limit=1000
]]

-- BAD: Multiple queries
for each item do
  local q1 = [[[[Item]]|?PropA]]
  local q2 = [[[[Item]]|?PropB]]
end

String Building[edit]

-- GOOD: Build array, concat once
local parts = {'<div>', content, '</div>'}
return table.concat(parts)

-- BAD: Repeated concatenation
local str = '<div>'
str = str .. content
str = str .. '</div>'
return str

Memory Management[edit]

-- GOOD: Local variables only
function getData()
  local result = query()
  return result
end

-- BAD: Module-level state
local cache = {}
function getData()
  cache[key] = query()
  return cache[key]
end

Testing[edit]

Unit Testing Data Functions[edit]

-- Test getAllVerseData
local data = require('Module:GetRootVerses/Data')
local result = data.getAllVerseData('1.1')

assert(result.bySource['001-Tsadra-BCA-Root-Padmakara'], 
       'Should have Tibetan source')
assert(#result.bySource['001-Tsadra-BCA-Root-Padmakara'].segments > 0,
       'Should have segments')

Integration Testing[edit]

<!-- Test on sandbox page -->
Test verse 1.1:
{{#invoke:GetRootVerses/sandbox|main|verse=1.1}}

Test missing verse:
{{#invoke:GetRootVerses/sandbox|main|verse=999.999}}

Test SimpleVerse:
{{#invoke:GetRootVerses/sandbox|SimpleVerse|verse=1.1|sources=001-Tsadra-BCA-Root-Padmakara}}

Debugging[edit]

Enable Debug Output[edit]

-- Temporary debug code
function p.main(frame)
    local verse = pargs.verse
    local allData = dataHelper.getAllVerseData(verse)
    
    -- Debug: show what we got
    local debug = mw.text.jsonEncode(allData.rootSources)
    return '<pre>' .. debug .. '</pre>'
end

Common Issues[edit]

No data returned:

-- Check query results
local results = smw.ask(query)
if not results then
    return 'Query returned nil'
end
if #results == 0 then
    return 'Query returned empty table'
end

Memory errors:

-- Check for module-level variables
-- These persist across pages:
local persistentData = {}  -- BAD

-- These don't:
function getData()
    local localData = {}   -- GOOD
end

Extending the Module[edit]

Adding a New Source[edit]

No code changes needed! The module automatically includes any source that:

  1. Is categorized as Translation Memory
  2. Has RootTextVerseNumPadmaK property set
  3. Has SegmentFormat set to "Root"
  4. Has RootSourceTransMem pointing to itself (for root sources)

Adding a New Display Feature[edit]

1. Add rendering function to Display module:

-- In Module:GetRootVerses/Display
function p.renderNewFeature(data, options)
    local parts = {'<div class="new-feature">'}
    -- Build HTML
    parts[#parts + 1] = '</div>'
    return table.concat(parts)
end

2. Call from main module:

-- In Module:GetRootVerses
local newFeature = displayHelper.renderNewFeature(data, {opt = 'value'})
parts[#parts + 1] = newFeature

Adding a New Data Source[edit]

To fetch from a new data source (beyond SMW):

-- In Module:GetRootVerses/Data
function p.getExternalData(identifier)
    local data = mw.ext.externalData.getExternalData{
        url = 'https://example.org/api?id=' .. identifier,
        data = { result = 'Result' },
        format = 'JSON'
    }
    return data.result
end

Maintenance Procedures[edit]

Updating After MediaWiki Upgrade[edit]

  1. Test basic functionality
  2. Check Scribunto version compatibility
  3. Verify SMW query syntax still works
  4. Test template expansions
  5. Monitor performance

Optimizing Queries[edit]

If queries become slow:

-- Add index hints
[[Category:Translation Memories]]  -- Indexed
[[RootTextVerseNumPadmaK::1.1]]   -- Should be indexed
[[SegmentFormat::Root]]            -- Should be indexed

-- Reduce limit if possible
|limit=1000  -- Try 500 if data allows

-- Request only needed properties
|?Prop1|?Prop2  -- Not |?Property::*

Code Style Guidelines[edit]

  • Use descriptive variable names
  • Comment complex logic
  • Keep functions under 50 lines
  • Prefer local variables
  • Use table.concat for string building
  • Validate input parameters
  • Return early on errors
  • Use helper functions for repeated code

Related Documentation[edit]