Installation Add the bundle via Composer:
composer require chitanka/wiki-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Chitanka\WikiBundle\ChitankaWikiBundle::class => ['all' => true],
];
Database Configuration
Configure the database connection in config/packages/chitanka_wiki.yaml:
chitanka_wiki:
db_driver: 'pdo_mysql'
db_host: '127.0.0.1'
db_port: '3306'
db_name: 'wiki_db'
db_user: 'wiki_user'
db_password: 'secure_password'
First Use Case: Creating a Wiki Page Run the migrations to set up the database schema:
php bin/console doctrine:migrations:migrate
Create a page via the CLI:
php bin/console wiki:page:create --title="Getting Started" --content="Welcome to the wiki!"
Basic Routing
The bundle provides a simple controller for viewing pages. Ensure your routes.yaml includes:
chitanka_wiki_page:
path: /wiki/{slug}
controller: Chitanka\WikiBundle\Controller\PageController::show
methods: GET
Creating Pages
Use the CLI for initial setup or extend the PageController for web-based creation:
// Example: Custom controller method for page creation
public function createPage(Request $request): Response
{
$title = $request->request->get('title');
$content = $request->request->get('content');
$page = $this->wikiManager->createPage($title, $content);
return $this->redirectToRoute('chitanka_wiki_page', ['slug' => $page->getSlug()]);
}
Editing Pages
Leverage the Page entity and its lifecycle callbacks (e.g., preUpdate) to handle Git-based versioning:
// Example: Custom logic before saving
public function preUpdate(Page $page): void
{
if ($page->isMajorEdit()) {
$this->gitService->commitChanges('Major update by ' . $page->getEditor());
}
}
Version Control Integration
Use the GitService to interact with the underlying Git repository:
// Example: Fetching page history
public function getPageHistory(string $slug): array
{
$page = $this->pageRepository->findOneBy(['slug' => $slug]);
return $this->gitService->getCommits($page->getPath());
}
Twig Integration Pass data to Twig templates for rendering:
// Example: Custom template context
public function show(string $slug, Request $request): Response
{
$page = $this->pageRepository->findOneBy(['slug' => $slug]);
return $this->render('wiki/page.html.twig', [
'page' => $page,
'history' => $this->gitService->getCommits($page->getPath()),
]);
}
Customizing the Git Repository
Override the GitService to use a custom repository path or hooks:
# config/packages/chitanka_wiki.yaml
chitanka_wiki:
git_repo_path: '%kernel.project_dir%/var/wiki_repo'
git_hooks_enabled: true
Extending the Page Entity
Add custom fields to the Page entity and update migrations:
// src/Entity/Page.php
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customField;
Event Listeners
Subscribe to events like page.created or page.updated for post-processing:
// src/EventListener/WikiListener.php
public function onPageCreated(PageEvent $event): void
{
$page = $event->getPage();
// Add custom logic (e.g., notifications)
}
Register the listener in services.yaml:
services:
App\EventListener\WikiListener:
tags:
- { name: 'kernel.event_listener', event: 'page.created', method: 'onPageCreated' }
API Endpoints Use Symfony’s serializers to expose wiki data via API:
// src/Controller/WikiApiController.php
#[Route('/api/wiki/{slug}', methods: ['GET'])]
public function getPage(string $slug): JsonResponse
{
$page = $this->pageRepository->findOneBy(['slug' => $slug]);
return $this->json($page, context: ['groups' => ['api']]);
}
Git Repository Initialization
cd %kernel.project_dir%/var/wiki_repo && git init
.gitignore file to exclude sensitive data (e.g., var/).Slug Conflicts
-2):
// Override slug generation in a custom service
public function generateSlug(string $title): string
{
$slug = Str::slug($title);
while ($this->pageRepository->findOneBy(['slug' => $slug])) {
$slug .= '-2';
}
return $slug;
}
Permission Issues
www-data) has write permissions for the Git repository:
chmod -R 775 %kernel.project_dir%/var/wiki_repo
Doctrine Migrations
chitanka_wiki.yaml to avoid connection errors.Git Hooks Failures
pre-commit) fail silently, enable verbose logging in config/packages/monolog.yaml:
handlers:
main:
type: stream
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
channels: ['!event']
Page Not Found
slug in the URL matches the database entry (case-sensitive). Use the wiki:page:list CLI command to debug:
php bin/console wiki:page:list
Content Not Rendering
content field in the Page entity is marked as text (not string) in Doctrine annotations:
/**
* @ORM\Column(type="text")
*/
private $content;
Custom Storage Backend
Replace the default database storage by implementing Chitanka\WikiBundle\Storage\PageStorageInterface:
// src/Storage/CustomPageStorage.php
class CustomPageStorage implements PageStorageInterface
{
public function save(Page $page): void
{
// Custom logic (e.g., save to Redis or S3)
}
}
Register the service in services.yaml:
services:
Chitanka\WikiBundle\Storage\PageStorageInterface: '@App\Storage\CustomPageStorage'
Markdown Support
Extend the bundle to render Markdown content using a library like parsedown:
// src/Twig/WikiExtension.php
public function getFunctions()
{
return [
new \Twig\TwigFunction('render_markdown', [$this, 'renderMarkdown']),
];
}
public function renderMarkdown(string $content): string
{
return (new \Parsedown())->text($content);
}
Use in Twig:
{{ page.content|render_markdown }}
Search Functionality
Integrate with a search engine (e.g., Elasticsearch) by extending the PageRepository:
// src/Repository/PageRepository.php
public function search(string $query): array
{
// Custom search logic
return $this->createQueryBuilder('p')
->where('p.title LIKE :query')
->setParameter('query', "%$query%")
->getQuery()
->getResult();
}
Access Control Implement custom permissions using Symfony’s voter system:
How can I help you explore Laravel packages today?