In the first part of this article I wrote about the planning around the conference website. I described the content types and the functionality we want to have. Now I will show you what happens after a speaker submits a talk.
As I wrote in the previous article the submitted talks are stored unpublished in the category “Talks”. The speakers get redirected to a “thank you” page with some information and the administrators get an e-mail informing about the new submission (this function is present in the plugin “Content - Joomla”).
In some months the team will sit together and will decide which talks are going to be part of the conference program. The accepted talks / articles will be published and the corresponding speaker / contact too. The team will inform the speakers and they will be able to edit their contact entry.
When speakers now login into the page they see the following
- Accepted talks: Articles Module showing only the title of the articles in the category talks filtered by current user
- My speaker profile: that is an own module listing the contact(s) associated with the current user. The link leads directly to the contact view which can be edited to add a photo, a description and some additional information.
The edit form for the contact has been simplified with an override similar to the edit form for content (explained in the previous article):
<?php
/**
* @package Joomla.Site
* @subpackage com_contact
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Contact\Administrator\Helper\ContactHelper;
use Joomla\Component\Contact\Site\Helper\RouteHelper;
/** @var \Joomla\Component\Contact\Site\View\Category\HtmlView $this */
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->getDocument()->getWebAssetManager();
$wa->useScript('core');
$canDo = ContactHelper::getActions('com_contact', 'category', $this->category->id);
$canEdit = $canDo->get('core.edit');
$userId = $this->getCurrentUser()->id;
$showEditColumn = false;
if ($canEdit) {
$showEditColumn = true;
} elseif ($canDo->get('core.edit.own') && !empty($this->items)) {
foreach ($this->items as $item) {
if ($item->created_by == $userId) {
$showEditColumn = true;
break;
}
}
}
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
?>
<div class="com-contact-category__items">
<?php if (empty($this->items)) : ?>
<?php if ($this->params->get('show_no_contacts', 1)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('COM_CONTACT_NO_CONTACTS'); ?>
</div>
<?php endif; ?>
<?php else : ?>
<div class="com-contact row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 gy-3" id="contactList">
<?php foreach ($this->items as $i => $item) : ?>
<?php if ($this->items[$i]->published == 0) : ?>
<div class="system-unpublished col">
<?php else : ?>
<div class="col" >
<?php endif; ?>
<?php if ($canEdit || ($canDo->get('core.edit.own') && $item->created_by === $userId)) : ?>
<div>
<?php echo HTMLHelper::_('contacticon.edit', $item, $this->params); ?>
</div>
<?php endif; ?>
<?php if ($item->published == 0) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JUNPUBLISHED'); ?>
</span>
</div>
<?php endif; ?>
<?php if ($item->publish_up && strtotime($item->publish_up) > strtotime(Factory::getDate())) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JNOTPUBLISHEDYET'); ?>
</span>
</div>
<?php endif; ?>
<?php if (!is_null($item->publish_down) && strtotime($item->publish_down) < strtotime(Factory::getDate())) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JEXPIRED'); ?>
</span>
</div>
<?php endif; ?>
<?php if ($item->published == -2) : ?>
<div>
<span class="badge bg-warning text-light">
<?php echo Text::_('JTRASHED'); ?>
</span>
</div>
<?php endif; ?>
<div class="com-contact-single card">
<?php if ($this->params->get('show_image_heading')) : ?>
<?php if ($item->image) : ?>
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => $item->image,
'alt' => $this->escape($item->name),
'class' => 'contact-thumbnail rounded-top-2 mb-3',
]
); ?>
<?php else : ?>
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => 'images/design/placeholder.png',
'alt' => $this->escape($item->name),
'class' => 'contact-thumbnail rounded-top-2 mb-3',
]
); ?>
<?php endif; ?>
<?php endif; ?>
<div class="px-2 d-flex flex-column align-items-center">
<h2>
<a href="<?php echo Route::_(RouteHelper::getContactRoute($item->slug, $item->catid, $item->language)); ?> " class="stretched-link">
<?php echo $this->escape($item->name); ?>
</a>
</h2>
<?php echo $item->event->afterDisplayTitle; ?>
<?php echo $item->event->beforeDisplayContent; ?>
<?php if ($this->params->get('show_position_headings') && !empty($item->con_position)) : ?>
<p><?php echo $item->con_position; ?></p>
<?php endif; ?>
<?php if ($this->params->get('show_country_headings') && !empty($item->country)) : ?>
<p><?php echo $item->country; ?></p>
<?php endif; ?>
<?php echo $item->event->afterDisplayContent; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($canDo->get('core.create')) : ?>
<?php echo HTMLHelper::_('contacticon.create', $this->category, $this->category->params); ?>
<?php endif; ?>
<?php if ($this->params->get('show_pagination', 2)) : ?>
<div class="com-contact-category__pagination w-100">
<?php if ($this->params->def('show_pagination_results', 1)) : ?>
<p class="com-contact-category__counter counter float-end pt-3 pe-2">
<?php echo $this->pagination->getPagesCounter(); ?>
</p>
<?php endif; ?>
<?php echo $this->pagination->getPagesLinks(); ?>
</div>
<?php endif; ?>
</div>
To avoid confusions we have installed the plugin “Restricted FS” (https://restrictedfs.dgrammatiko.dev/) that restrict the upload of images to a specific folder per user.
For the speakers we have prepared some overrides. For the category view:
Override of default_items.php
<?php
/**
* @package Joomla.Site
* @subpackage com_contact
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Contact\Administrator\Helper\ContactHelper;
use Joomla\Component\Contact\Site\Helper\RouteHelper;
/** @var \Joomla\Component\Contact\Site\View\Category\HtmlView $this */
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->getDocument()->getWebAssetManager();
$wa->useScript('core');
$canDo = ContactHelper::getActions('com_contact', 'category', $this->category->id);
$canEdit = $canDo->get('core.edit');
$userId = $this->getCurrentUser()->id;
$showEditColumn = false;
if ($canEdit) {
$showEditColumn = true;
} elseif ($canDo->get('core.edit.own') && !empty($this->items)) {
foreach ($this->items as $item) {
if ($item->created_by == $userId) {
$showEditColumn = true;
break;
}
}
}
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
?>
<div class="com-contact-category__items">
<?php if (empty($this->items)) : ?>
<?php if ($this->params->get('show_no_contacts', 1)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('COM_CONTACT_NO_CONTACTS'); ?>
</div>
<?php endif; ?>
<?php else : ?>
<div class="com-contact row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 gy-3 mb-2" id="contactList">
<?php foreach ($this->items as $i => $item) : ?>
<?php if ($this->items[$i]->published == 0) : ?>
<div class="system-unpublished col">
<?php else : ?>
<div class="col" >
<?php endif; ?>
<div class="com-contact-single card">
<?php if ($this->params->get('show_image_heading')) : ?>
<?php if ($item->image) : ?>
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => $item->image,
'alt' => $this->escape($item->name),
'class' => 'contact-thumbnail rounded-top-2 mb-3',
]
); ?>
<?php else : ?>
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => 'images/design/placeholder.png',
'alt' => $this->escape($item->name),
'class' => 'contact-thumbnail rounded-top-2 mb-3',
]
); ?>
<?php endif; ?>
<?php endif; ?>
<div class="px-2 d-flex flex-column align-items-center">
<h2>
<a href="<?php echo Route::_(RouteHelper::getContactRoute($item->slug, $item->catid, $item->language)); ?> " class="stretched-link">
<?php echo $this->escape($item->name); ?>
</a>
</h2>
<?php echo $item->event->afterDisplayTitle; ?>
<?php echo $item->event->beforeDisplayContent; ?>
<?php if ($this->params->get('show_position_headings') && !empty($item->con_position)) : ?>
<p><?php echo $item->con_position; ?></p>
<?php endif; ?>
<?php if ($this->params->get('show_country_headings') && !empty($item->country)) : ?>
<p><?php echo $item->country; ?></p>
<?php endif; ?>
<?php echo $item->event->afterDisplayContent; ?>
<?php if ($canEdit || ($canDo->get('core.edit.own') && $item->created_by === $userId)) : ?>
<div>
<?php echo HTMLHelper::_('contacticon.edit', $item, $this->params); ?>
</div>
<?php endif; ?>
<?php if ($item->published == 0) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JUNPUBLISHED'); ?>
</span>
</div>
<?php endif; ?>
<?php if ($item->publish_up && strtotime($item->publish_up) > strtotime(Factory::getDate())) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JNOTPUBLISHEDYET'); ?>
</span>
</div>
<?php endif; ?>
<?php if (!is_null($item->publish_down) && strtotime($item->publish_down) < strtotime(Factory::getDate())) : ?>
<div>
<span class="list-published badge bg-warning text-light">
<?php echo Text::_('JEXPIRED'); ?>
</span>
</div>
<?php endif; ?>
<?php if ($item->published == -2) : ?>
<div>
<span class="badge bg-warning text-light">
<?php echo Text::_('JTRASHED'); ?>
</span>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($canDo->get('core.create')) : ?>
<?php echo HTMLHelper::_('contacticon.create', $this->category, $this->category->params); ?>
<?php endif; ?>
<?php if ($this->params->get('show_pagination', 2)) : ?>
<div class="com-contact-category__pagination w-100">
<?php if ($this->params->def('show_pagination_results', 1)) : ?>
<p class="com-contact-category__counter counter float-end pt-3 pe-2">
<?php echo $this->pagination->getPagesCounter(); ?>
</p>
<?php endif; ?>
<?php echo $this->pagination->getPagesLinks(); ?>
</div>
<?php endif; ?>
</div>
And for the contact:
Override of default.php:
<?php
/**
* @package Joomla.Site
* @subpackage com_contact
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use Joomla\Component\Contact\Site\Helper\RouteHelper;
/** @var \Joomla\Component\Contact\Site\View\Contact\HtmlView $this */
$tparams = $this->item->params;
$canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid);
$canEdit = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by === $this->getCurrentUser()->id);
$htag = $tparams->get('show_page_heading') ? 'h2' : 'h1';
$htag2 = ($tparams->get('show_page_heading') && $tparams->get('show_name')) ? 'h3' : 'h2';
$icon = $this->params->get('contact_icons') == 0;
?>
<div class="com-contact contact">
<?php if ($tparams->get('show_page_heading')) : ?>
<h1>
<?php echo $this->escape($tparams->get('page_heading')); ?>
</h1>
<?php endif; ?>
<?php if ($this->item->name && $tparams->get('show_name')) : ?>
<div class="page-header">
<<?php echo $htag; ?>>
<?php if ($this->item->published == 0) : ?>
<span class="badge bg-warning text-light"><?php echo Text::_('JUNPUBLISHED'); ?></span>
<?php endif; ?>
<span class="contact-name"><?php echo $this->item->name; ?></span>
</<?php echo $htag; ?>>
</div>
<?php endif; ?>
<?php if ($canEdit) : ?>
<div class="icons">
<div class="float-end">
<div>
<?php echo HTMLHelper::_('contacticon.edit', $this->item, $tparams); ?>
</div>
</div>
</div>
<?php endif; ?>
<?php echo $this->item->event->afterDisplayTitle; ?>
<?php if ($tparams->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
<div class="com-contact__tags">
<?php $this->item->tagLayout = new FileLayout('joomla.content.tags'); ?>
<?php echo $this->item->tagLayout->render($this->item->tags->itemTags); ?>
</div>
<?php endif; ?>
<?php echo $this->item->event->beforeDisplayContent; ?>
<?php if ($this->params->get('show_info', 1)) : ?>
<div class="row mb-5">
<?php if ($this->item->image && $tparams->get('show_image')) : ?>
<div class="col-sm-4">
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => $this->item->image,
'alt' => $this->item->name,
'class' => 'rounded-2',
]
); ?>
</div>
<?php endif; ?>
<div class="col-sm-8">
<p><?php echo $this->item->country; ?></p>
<?php if ($this->item->con_position && $tparams->get('show_position')) : ?>
<p><?php echo $this->item->con_position; ?></p>
<?php endif; ?>
<?php if ($this->item->misc && $tparams->get('show_misc')) : ?>
<?php echo $this->item->misc; ?>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php if ($tparams->get('show_articles') && $this->item->user_id && $this->item->articles) : ?>
<?php echo '<' . $htag2 . '>' . Text::_('JWC_TALKS') . '</' . $htag2 . '>'; ?>
<?php echo $this->loadTemplate('articles'); ?>
<?php endif; ?>
<?php if ($tparams->get('show_profile') && $this->item->user_id && PluginHelper::isEnabled('user', 'profile')) : ?>
<?php echo '<' . $htag2 . '>' . Text::_('COM_CONTACT_PROFILE') . '</' . $htag2 . '>'; ?>
<?php echo $this->loadTemplate('profile'); ?>
<?php endif; ?>
<?php if ($tparams->get('show_user_custom_fields') && $this->contactUser) : ?>
<?php echo $this->loadTemplate('user_custom_fields'); ?>
<?php endif; ?>
<?php echo $this->item->event->afterDisplayContent; ?>
</div>
The talks (articles) from the speaker are listed below the profile. That is possible setting the parameter “User Articles” to “Show” in the menu item:
The title “My talk(s) is a language override:
The program of the conference will also be created using Joomla Core. How? That will be the topic of my next article ;-)
Don’t forget to visit the conference website: https://conference.joomla.org/. Think about joining the international Joomla Community in October and if you have something special to talk about, please submit your session!