Learn Language

unlisted

by Juanjo Arranz

Advanced Learn Language Management for Obsidian

Updated 1mo ago
View on GitHub

Learn Language Plugin for Obsidian

A flexible language learning management plugin for Obsidian that supports any language pair. Features dictionary management, verb conjugation reference, interactive filtering, and OpenAI integration for AI-assisted term creation.

Features

๐ŸŒ Multi-Language Support

  • Configurable language pair: Learn any language from any source language
  • Supports 25+ languages with automatic locale-based sorting
  • Dynamic UI labels based on your configured languages

๐Ÿ“š Dictionary Management

  • View and filter all dictionary entries from your vault
  • Advanced filtering by target word, source translation, type, context, and revision status
  • Pagination support for large dictionaries
  • Quick access via ribbon icon or command palette

๐Ÿ”ค Verb Conjugation Reference

  • Dedicated view for verb entries
  • Filter by verb group (1, 2, 3, irregular)
  • Display conjugations: Prรฉsent, Subjonctif, Imparfait, Passรฉ composรฉ, Futur
  • Track irregular verbs

๐Ÿ“– Study Mode (Flashcards)

  • Toggle between normal view and study mode
  • Target โ†’ Source or Source โ†’ Target directions
  • Collapsible answers for self-testing
  • Works in both Dictionary and Verbs views

๐Ÿค– OpenAI Integration

  • AI-assisted term creation and classification
  • Automatic translation suggestions
  • Term type and context classification based on your custom taxonomies
  • Auto-sync of type/context files with OpenAI Assistant

๐Ÿ” Advanced Filtering

  • Filter by any property (target word, source word, Type, Context, Revision)
  • Type-ahead search for target and source word filters (real-time filtering as you type)
  • Hierarchical tag expansion (e.g., #verbe/rรฉgulier/1 matches #verbe)
  • Locale-aware sorting based on target language
  • Filter state persistence

๐Ÿ“ Embed Dictionary in Notes

  • Use the learn-dictionary code block to embed an interactive dictionary directly in any note
  • Full filtering and pagination support within the embedded view
  • Same UI and functionality as the sidebar view
  • Configure initial filters via YAML-like options
  • Optional export of the currently filtered results to a delimited .txt file

Installation

From Obsidian Community Plugins (Coming Soon)

  1. Open Settings โ†’ Community plugins
  2. Search for "Learn Language"
  3. Install and enable

Manual Installation

  1. Download the latest release from GitHub
  2. Extract to your vault's .obsidian/plugins/learn-language/ folder
  3. Reload Obsidian
  4. Enable the plugin in Settings โ†’ Community plugins

Build from Source

cd learn-language-plugin
npm install
npm run build

Copy main.js, manifest.json, and styles.css to your vault's .obsidian/plugins/learn-language/ folder.

Configuration

Go to Settings โ†’ Learn Language to configure:

Language Configuration

  • Target language: The language you are learning (e.g., French, German, Italian)
  • Source language: Your native/source language (e.g., Spanish, English)

The plugin automatically determines the correct locale for sorting based on the language name. Supported languages include: French, Spanish, Italian, Portuguese, German, English, Dutch, Swedish, Russian, Polish, Japanese, Chinese, Korean, Greek, Turkish, Arabic, and many more.

Note: The language names are also used to find the corresponding frontmatter fields in your notes. For example, if Target language is "French" and Source language is "Spanish", the plugin will look for French: and Spanish: fields in your note frontmatter.

Folder Paths

  • Dictionary folder: Where your dictionary entries are stored (default: 10. Dictionary)
  • Verbs folder: Optional separate folder for verbs
  • Grammar folder: Grammar resources location
  • Templates folder: Note templates location

Classification Files

  • Term types file: File containing term type definitions (e.g., #verbe, #nom, #expression)
  • Context types file: File containing context definitions (e.g., #social, #culinary)

OpenAI Settings

  • API Key: Your OpenAI API key
  • Auto-sync: Automatically update types/context files in OpenAI when they change

Usage

Commands

Access via Command Palette (Ctrl/Cmd + P):

CommandDescription
Open Dictionary ViewOpen the dictionary browser
Open Verbs ViewOpen the verbs browser
Create New TermOpen modal to create a new dictionary entry
Ask AI for TermQuick AI lookup and term creation
Edit Current TermEdit the currently open dictionary entry
Refresh Dictionary CacheForce reload of dictionary data
Reset OpenAI ConversationStart fresh AI conversation thread

Ribbon Icons

  • ๐Ÿ“– Book icon: Open Dictionary View
  • ๐Ÿ—ฃ๏ธ Languages icon: Open Verbs View
  • โž• Plus icon: Create New Term

Dictionary Entry Structure

Your dictionary entries should follow this structure:

---
Spanish: translation
cssclasses:
  - ja-readable
---

Type:: #verbe/rรฉgulier/1
Synonyms::
Context:: #social/greetings
Examples:: Bonjour, comment allez-vous?<br>Bonjour ร  tous!
Rating:: #โญโญ
Relations::
Revision:: 1
Project:: [[Learn French]]

Embedding Dictionary in Notes

You can embed an interactive dictionary view directly in any note using the learn-dictionary code block:

```learn-dictionary
type: verb
context: A1
pageSize: 25
```

Available Options

OptionDescriptionDefault
targetWordInitial filter for target word (type-ahead search)all
sourceWordInitial filter for source word (type-ahead search)all
typeFilter by type (verb, noun, expression, etc.)all
contextFilter by context (A1, A2, social, etc.)all
revisionFilter by revision statusall
studyStudy mode (no, yes, source)no
limitMaximum number of entries to loadno limit
pageSizeEntries per page50
showStudyShow study mode toggletrue
showPaginationShow pagination controlstrue
allowExportShow an Export button to export filtered resultsfalse

Export (TXT)

When allowExport: true, an Export button is displayed in the embedded dictionary.

Clicking Export opens a modal that exports the currently filtered rows to a delimited .txt file.

Modal options:

  • Pages: export all pages (default) or select specific pages from the filtered result set
  • File name: output file name (default: dictionary-export.txt)
  • Folder: absolute folder path where the file will be saved (includes a desktop folder picker)
  • Separator: field separator (| default, or ;)
  • Fields: choose which fields to export (checkboxes)

Special handling:

  • If Examples is selected, exported values:
    • Replace <br>/<br/>/<br /> with real newlines
    • Remove italics (both HTML <em>/<i> and markdown emphasis like *text* / _text_)

Note: The folder picker and writing to an absolute path require Obsidian Desktop.

Examples

Show only verbs with context A1:

```learn-dictionary
type: verb
context: A1
pageSize: 20
```

Simple embedded dictionary with 100 entries max:

```learn-dictionary
limit: 100
showStudy: false
```

Full dictionary with all options:

```learn-dictionary
type: expression
context: social
pageSize: 50
showStudy: true
showPagination: true
```

Note: The embedded dictionary uses the same DictionaryComponent as the sidebar view, so all interactive features (type-ahead search, filters, pagination, study mode) work identically.

Global API (Dataview Compatibility)

The plugin exposes a global API for use in Dataview scripts:

// Access the plugin API
const learnLanguage = app.plugins.plugins["learn-language"];
const api = learnLanguage.api;

// Get language configuration
const targetLang = api.targetLanguage;  // e.g., "French"
const sourceLang = api.sourceLanguage;  // e.g., "Spanish"

// Get all dictionary entries
const entries = await api.getDictionary();

// Get all verbs
const verbs = await api.getVerbs();

// Get grammar pages
const grammar = await api.getGrammarPages();

// Filter entries
const filtered = api.filterEntries(entries, {
  type: "#verbe",
  context: "#social"
});

// Paginate results
const page = api.paginateEntries(filtered, 0, 100);

// Ask AI for a term
const response = await api.askAI("bonjour");

// Create a new term
await api.createTerm({
  targetWord: "bonjour",
  sourceWord: "hola",
  type: "#expression",
  context: "#social/greetings"
});

Entry Structure

Dictionary entries returned by the API have these properties:

PropertyDescription
fileObject with path, name, basename
targetWordThe word in target language (lowercase)
sourceWordTranslation in source language (lowercase)
typeTerm type tags (e.g., #verbe, #nom)
contextContext tags (e.g., #social, #culinary)
revisionRevision status (new, 1, 2, etc.)
ratingOptional rating
examplesUsage examples
synonymsRelated synonyms
relationsRelated terms
projectAssociated project

Example: Dynamic Table Headers

const api = app.plugins.plugins["learn-language"].api;
const entries = await api.getDictionary();

// Use configured language names as headers
dv.table(
    [api.targetLanguage, api.sourceLanguage, "Type", "Examples"],
    entries.slice(0, 20).map(e => [
        dv.fileLink(e.file.path, false, e.file.name),
        e.sourceWord || "",
        e.type || "",
        e.examples || ""
    ])
);

Migration from Dataview Scripts

If you're migrating from the previous Dataview-based implementation:

  1. Install the plugin and configure folder paths in settings
  2. Keep your existing queries - they'll continue to work via the global API
  3. Gradually migrate to plugin views for better performance
  4. Move OpenAI settings from JSON file to plugin settings

Legacy Support

The plugin includes CSS classes from the original implementation:

  • ja-readable, ja-dictionary, ja-mobile
  • ja-sticky-header, ja-table-verbs
  • ja-filter-active, ja-collapsible

Development

# Install dependencies
npm install

# Build for development (watch mode)
npm run dev

# Build for production
npm run build

Project Structure

learn-language-plugin/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ main.ts                    # Plugin entry point
โ”‚   โ”œโ”€โ”€ types.ts                   # TypeScript types and interfaces
โ”‚   โ”œโ”€โ”€ settings.ts                # Settings tab
โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ”œโ”€โ”€ DictionaryService.ts   # Data management
โ”‚   โ”‚   โ”œโ”€โ”€ OpenAIService.ts       # AI integration
โ”‚   โ”‚   โ”œโ”€โ”€ TermService.ts         # Term CRUD operations
โ”‚   โ”‚   โ””โ”€โ”€ FilterService.ts       # Filtering logic
โ”‚   โ”œโ”€โ”€ context/
โ”‚   โ”‚   โ””โ”€โ”€ LearnLanguageContext.tsx  # React context provider
โ”‚   โ”œโ”€โ”€ hooks/
โ”‚   โ”‚   โ”œโ”€โ”€ useFilters.ts          # Filter state management hook
โ”‚   โ”‚   โ”œโ”€โ”€ usePagination.ts       # Pagination hook
โ”‚   โ”‚   โ”œโ”€โ”€ useFilteredEntries.ts  # Filtered data hook
โ”‚   โ”‚   โ”œโ”€โ”€ useTypeAhead.ts        # Type-ahead search hook
โ”‚   โ”‚   โ””โ”€โ”€ useDebounce.ts         # Debounce utility hook
โ”‚   โ”œโ”€โ”€ views/
โ”‚   โ”‚   โ”œโ”€โ”€ DictionaryView.tsx     # Dictionary sidebar (React)
โ”‚   โ”‚   โ””โ”€โ”€ VerbsView.tsx          # Verbs sidebar (React)
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ dictionary/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ DictionaryComponent.tsx  # Main dictionary component
โ”‚   โ”‚   โ”œโ”€โ”€ verbs/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ VerbsComponent.tsx       # Main verbs component
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ VerbsTable.tsx           # Verbs table with conjugations
โ”‚   โ”‚   โ”œโ”€โ”€ filters/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ TypeAheadFilter.tsx      # Type-ahead search input
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ DropdownFilter.tsx       # Dropdown select filter
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ StudyToggle.tsx          # Study mode toggle
โ”‚   โ”‚   โ””โ”€โ”€ table/
โ”‚   โ”‚       โ”œโ”€โ”€ DictionaryTable.tsx      # Dictionary entries table
โ”‚   โ”‚       โ””โ”€โ”€ Pagination.tsx           # Pagination controls
โ”‚   โ”œโ”€โ”€ processors/
โ”‚   โ”‚   โ””โ”€โ”€ DictionaryCodeBlockProcessor.tsx  # Embed dictionary in notes
โ”‚   โ”œโ”€โ”€ utils/
โ”‚   โ”‚   โ””โ”€โ”€ reactMount.tsx         # React mounting utilities
โ”‚   โ””โ”€โ”€ modals/
โ”‚       โ””โ”€โ”€ TermModal.ts           # Term create/edit modal
โ”œโ”€โ”€ styles.css                     # Plugin styles
โ”œโ”€โ”€ manifest.json                  # Plugin manifest
โ”œโ”€โ”€ package.json                   # NPM configuration
โ””โ”€โ”€ tsconfig.json                  # TypeScript config (JSX support)

React Architecture

The plugin uses React 18 for all UI components:

  • Context Provider (LearnLanguageContext): Shares app, settings, filterService, and dictionaryService across all components
  • Custom Hooks: Encapsulate state logic for filters, pagination, debouncing, and data fetching
  • Component Composition: Modular components for filters, tables, and controls
  • React Mounting: Views use createRoot() for mounting React components within Obsidian's ItemView system

License

MIT License - see LICENSE file for details.

Author

Juanjo Arranz

Acknowledgments

  • Built for use with the Obsidian Dataview plugin
  • OpenAI GPT-4 for AI-assisted features
  • Inspired by language learning methodologies

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.