Шаблоны Joomla 3 тут

При разработке сложных программ с богатой функциональностью часто приходится прибегать к модульному построению:
функциональность реализуется с помощью системы библиотек, модулей, плагинов, а само приложение является лишь основой, каркасом, отвечающим за передачу данных между модулями. Помимо чисто технических преимуществ, таких как удобство разработки, сокращение расхода памяти, итд, этот подход позволяет создавать расширяемые приложения, в том числе расширяемые с помощью модулей сторонних разработчиков, а также строить "системы программ" - комплексы, в
которых модулями являются не разделяемые библиотеки, а полновесные программы, иногда со своим собственным графическим интерфейсом. при этом передача информации (данных и команд) между приложением-скелетом (или, как его еще называют, фреймворком) и модулями может осуществляться как вычурными способами, типа вызовов rpc, связи по tcp-ip, так и банальным обменом файлами.
Хорошим примером фреймворков являются системы сквозного проектирования в микроэлектронике, где в единый комплекс объединены столь разные программы, как редакторы принципиальных схем, топологий, симуляторы, трассировщики, верификаторы, дополнительные сервисные утилиты, конверторы, распараллеливатели и.т.д.

При разработке программ такого класса сталкиваются со стереотипным рядом проблем

1) часть модулей еще не до конца готова или вообще отсутствуют -
   вместо модулей или отдельных их функций используются заглушки
2) для "сшивания" воедино множества модулей требуется собственный язык
3) многоуровневые вызовы, таящиеся за нажатием единственной кнопки в GUI
   требуют развитой системы логов для эффективной отладки
4) конфигурирование монстра, включающего отдельные программы со своими
   собственными конфигами
5) функциональность модулей столь велика, что даже автор уже не упомнит всех
   функций и способов их вызова

Очевидно, что система визуального манипулирования объектной базой данных, рассчитанная на постоянное усложнение и доработку как графической части, так и СУБД является весьма подходящим кандидатом на реализацию в виде фреймворка.

Итак, что же нам придется изменить в написании приложения?

Было: нажатие на кнопку ГУИ запускает процедуру-обработчик (возможно из другого паскалевского модуля), которая выполняет требуемые действия.
Стало: нажатие на кнопку ГУИ запускает процедуру-обработчик, которая формирует
 команду и ставит ее в очередь.
 интерпретатор выбирает команды из очереди, отдает их в нужный модуль для
 исполнения, результат выполнения заносит в лог (если включен режим отладки)
 по мере исполнения

Бонусы:
1) обо всех модулях программы знает только модуль-интерпретатор
   - изменения вносятся централизованно
2) обо всех функциях модуля-исполнителя знает только сам модуль-исполнитель.
   - все изменения логики локализуются в соответствующем модуле и не имеют
     шансов быть размазаны по всей программе, где за ними сложно уследить
3) интерпретатору и исполнителям неважно, как именно была сгенерирована команда
   нажатием одной или другой кнопки или вообще чтением из файла. таким образом
   можно
   - крайне легко изменять интерфейс
   - вести журнал действий пользователя (разумеется, тех, которые
   представлены командами)
   - "воспроизводить" заранее записанные последовательности команд, т.е. скрипты
4) в принципе, интерпретатор может выполнять несколько команд в параллель
   например, запуск нескольких подпроцессов с командами ОС и.т.д.
5) интерпретатор может учитывать приоритет команд, замедлять или ускорять
   выполнение разных веток программы
6) можно запустить несколько копий интерпретатора для однеовременной работы над
   несколькими объектами
7) интерпретатор может иметь специальные команды управления интерпретатором,
   что позволяет строить самомодифицирующиеся скрипты.
Минусы:
1) потеря производительности
2) громоздкость
 
На данный момент описанный подход частично реализован в модуле interpreter.pas
Как это устроено:
форма интерпретатора становится главной (с точки зрения Лазаруса) формой приложения. Эта форма содержит список всех модулей, список команд выбранного модуля, поле для ручного редактирования команды, список команд (скрипт) и элементы управления ходом выполнения скрипта.



В секции Implementation надо перечислить все модули-исполнители

Uses unit1,Config,DBManage2;
В конец процедуры InitModule надо вписать вызовы процедур InitModule соответствующих модулей-исполнителей.

  Config.InitModule;
  DBManage2.InitModule;
  Unit1.InitModule;

В самих модулях-исполнителях в дополнение к "потрохам" модуля понадобится вот
что:

Var     ICommands:TStringList;

Procedure InitModule;
Procedure ExecCommand(Command:String);

Implementation
Uses Interpreter;

Procedure InitModule;
Begin
  InterpreterForm.ModulesList.Items.Add('Config');
  ICommands:=TStringList.Create;
  ICommands.Add('Config::clear:');
  ICommands.Add('Config::load:<file>');
End;

Здесь мы видим, как модуль-исполнитель сообщает интерпретатору свое название и список своих команд, причем в таком формате, который должен помочь человеку правильно оформить команду при ручном редактировании. В принципе, такое описание формата можно применить и при парсинге приходящих в модуль команд, но пока собственно интерпретация выглядит так

Function ExecCommand(Command:String):String;
var B,PB,Obj,Cmd,Attr:String;
Begin
  Obj:=GetNextToken(Command,PB,':');
  B:=PB;
  Cmd:=GetNextToken(B,PB,':');
  Attr:=PB;
  If Obj='' Then Begin
    If LowerCase(Cmd)='clear' Then ConfigFile.Clear;
    If LowerCase(Cmd)='load' Then
       If Attr='' Then LoadConfigFile
       Else LoadConfigPart(Attr);
  End;
End;

Как это работает:
команды отдаются процедурами
Procedure QueueCommand(Command:String);
Procedure QueueMultipleCommands(Commands:TStringList);

формат команды - текстовая строка, состоящая из следующих полей
-модуль-исполнитель
-объект
-имя команды
-параметры
имя модуля отделяется двоеточием, остальное зависит только от того, как реализован парсинг в процедуре ExecCommand модулей-исполнителей.

Команда(ы) попадает в очередь, откуда выбирается интерпретатором. Он откусывает от команды имя модуля (вместе с последующим двоеточием) и передает остаток интерпретатору соответствующего модуля.