2

I am creating an override in DP calendar and would like to display a custom field created in DP Calendar inside the module. The field type is 'URL' thus I would like it to be a clickable link. I have been unable to find any documentation as to how I can do this.

The below code is the module override. The link I would like to replace with the custom field is the Register link. The name of the custom field is 'reglink':

<?php
/**
 * @package    DPCalendar
 * @author     Digital Peak http://www.digital-peak.com
 * @copyright  Copyright (C) 2007 - 2019 Digital Peak. All rights reserved.
 * @license    http://www.gnu.org/licenses/gpl.html GNU/GPL
 */
defined('_JEXEC') or die();

if (!$events) {
    echo JText::_('MOD_DPCALENDAR_UPCOMING_NO_EVENT_TEXT');

    return;
}

require JModuleHelper::getLayoutPath('mod_dpcalendar_upcoming', '_scripts');
?>
<div class="mod-dpcalendar-upcoming mod-dpcalendar-upcoming-simple mod-dpcalendar-upcoming-<?php echo $module->id; ?>">
    <?php foreach ($groupedEvents as $groupHeading => $events) { ?>
        <?php if ($groupHeading) { ?>
            <div class="mod-dpcalendar-upcoming-simple__group">
            <p class="mod-dpcalendar-upcoming-simple__heading dp-group-heading"><?php echo $groupHeading; ?></p>
        <?php } ?>
        <?php foreach ($events as $index => $event) { ?>
            <?php $startDate = $dateHelper->getDate($event->start_date, $event->all_day); ?>
            <div class="mod-dpcalendar-upcoming-simple__event">
                <div class="row">
                <div class="mod-dpcalendar-upcoming-simple__date col-md-4 event-num">
                    <?php echo $dateHelper->getDateStringFromEvent($event, $params->get('date_format'), $params->get('time_format')); ?>
                </div>              
                <div class="mod-dpcalendar-upcoming-simple__information col-md-8">
                    <a href="<?php echo $event->realUrl; ?>" class="dp-event-url dp-link"><?php echo $event->title; ?></a>
                    <p><a href="<?php echo $event->realUrl; ?>" class="dp-event-url dp-link more">More Info >></a>
                    <a href="<?php echo $event->realUrl; ?>" class="dp-event-url dp-link register-dp">Register >></a></p>
                    <?php if ($params->get('show_location') && isset($event->locations) && $event->locations) { ?>
                        <?php foreach ($event->locations as $location) { ?>
                            <span class="mod-dpcalendar-upcoming-simple__location"
                                  data-latitude="<?php echo $location->latitude; ?>"
                                  data-longitude="<?php echo $location->longitude; ?>"
                                  data-title="<?php echo $location->title; ?>">
                                <a href="<?php echo $router->getLocationRoute($location); ?>" class="dp-link">
                                    <?php echo $location->title; ?>
                                </a>
                            </span>
                        <?php } ?>
                    <?php } ?>
                </div>
            </div> <!-- End of event row -->
                <?php if ($event->images->image_intro) { ?>
                    <div class="mod-dpcalendar-upcoming-simple__image">test
                        <figure class="dp-figure">
                            <img class="dp-image" src="<?php echo $event->images->image_intro; ?>"
                                 alt="<?php echo $event->images->image_intro_alt; ?>">
                            <?php if ($event->images->image_intro_caption) { ?>
                                <figcaption class="dp-figure__caption"><?php echo $event->images->image_intro_caption; ?></figcaption>
                            <?php } ?>
                        </figure>
                    </div>
                <?php } ?>
                <?php if ($params->get('show_booking', 1) && \DPCalendar\Helper\Booking::openForBooking($event)) { ?>
                    <a href="<?php echo $router->getBookingFormRouteFromEvent($event, $return); ?>" class="dp-link dp-link_cta dp-button">
                        <?php echo $layoutHelper->renderLayout('block.icon', ['icon' => \DPCalendar\HTML\Block\Icon::PLUS]); ?>
                        <?php echo $translator->translate('MOD_DPCALENDAR_UPCOMING_BOOK'); ?>
                    </a>
                <?php } ?>
                <div class="mod-dpcalendar-upcoming-simple__description">
                    <?php echo $event->truncatedDescription; ?>
                </div>
                <?php $displayData['event'] = $event; ?>
                <?php echo $layoutHelper->renderLayout('schema.event', $displayData); ?>
            </div>
        <?php } ?>
        <?php if ($groupHeading) { ?>
            </div>
        <?php } ?>
    <?php } ?>
</div>

I've had a look at the render.php file for the custom fields but am struggling to understand which code I need to copy into the override file. The render.php is below:

<?php
/**
 * @package    DPCalendar
 * @author     Digital Peak http://www.digital-peak.com
 * @copyright  Copyright (C) 2007 - 2019 Digital Peak. All rights reserved.
 * @license    http://www.gnu.org/licenses/gpl.html GNU/GPL
 */
defined('_JEXEC') or die();

if (!key_exists('item', $displayData) || !key_exists('context', $displayData)) {
    return;
}

$item = $displayData['item'];

if (!$item) {
    return;
}

$context = $displayData['context'];

if (!$context) {
    return;
}

JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');

$parts     = explode('.', $context);
$component = $parts[0];
$fields    = array();

if (key_exists('fields', $displayData)) {
    $fields = $displayData['fields'];
} else {
    if (!empty($item->jcfields)) {
        $fields = $item->jcfields;
    }

    if (!$fields) {
        $fields = FieldsHelper::getFields($context, $item, true);
    }
}
if (!$fields) {
    return;
}
?>
<div class="dp-fields">
    <?php foreach ($fields as $field) { ?>
        <?php if (!isset($field->value) || $field->value == '') { ?>
            <?php continue; ?>
        <?php } ?>
        <dl class="dp-description dp-field-<?php echo $field->name; ?> <?php echo $field->params->get('render_class'); ?>">
            <dt class="dp-description__label"><?php echo $field->params->get('showlabel', 1) ? JText::_($field->label) : ''; ?></dt>
            <dd class="dp-description__description"><?php echo $field->value; ?></dd>
        </dl>
    <?php } ?>
</div>

Could anybody maybe point me in the right direction with this?

Regards

D

3
  • Have you contacted the developer?
    – jonboy
    Commented Feb 14, 2020 at 9:19
  • @jonboy My current subscription has expired and i'm not willing to purchase a new one if I can't get this to work. They do not have a support forum and their documentation just refers back to Joomla custom fields - joomla.digital-peak.com/documentation/dpcalendar/configuration/… which isn't overly helpful in this case. I'm not overly familiar with calling a custom field into a module. so i'm just looking for a pointer. I've tried to follow the Joomla documentation without success. Any suggestions are very much welcome :)
    – Dtorr1981
    Commented Feb 16, 2020 at 0:31
  • @Dtorr1981 Hello. Which version of DPCalendar do you have? Commented Feb 20, 2020 at 22:46

3 Answers 3

2
+25

As mentioned in the other answer, https://docs.joomla.org/J3.x:Adding_custom_fields/Overrides is the key description to understand. To quote:

Basically you have all the custom fields corresponding to the current item accessible via a new property in your $item variable called jcfields.

and that Joomla documentation page lists all the fields of the jcfields array.

In the DP Calendar mod_dpcalendar_upcoming module the items are held in the variable $events, and the code iterates over $events from the line

<?php foreach ($events as $index => $event) { 

so that within that foreach loop $event->jcfields is an array of data relating to the custom fields which you have, one array element for each custom field.

So what you need to do is create an override for the mod_dpcalendar_upcoming module as described in https://docs.joomla.orgJ3.x:How_to_use_the_Template_Manager#Creating_Overrides.

Then you need to edit the override default.php file (which you show in your question) so that the reglink field is output, again as described in https://docs.joomla.org/J3.x:Adding_custom_fields/Overrides.

First of all, add near the top of the default.php file the line

JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); 

Then output the reglink field wherever you want it to appear by including the following code:

<?php foreach ($event->jcfields as $field) {
        if ($field->name = "reglink") {
            echo FieldsHelper::render($field->context, 'field.render', array('field' => $field));
            break;
        } 
    }  ?>

(I tried it out just above the line with if ($params->get('show_price') ...).

Alternatively you can just output the URL (without the field label) with

echo $field->value;

instead of echoing the FieldsHelper::render call.

1

I have never used DPCalendar, so your mileage may vary, but I've had some luck tinkering with getting custom fields in overrides like this:

 $item->jcfields[n]->rawvalue;

n in this example is the array position of the desired custom field. Raw value retrieves the data.

Here is a nice explanation in the Joomla documentation.

https://docs.joomla.org/J3.x:Adding_custom_fields/Overrides/en

1
  • Welcome to JSE and thank you for contributing. Please take the tour and perhaps introduce yourself on your profile page. Commented Feb 20, 2020 at 3:06
1

What you try to achieve is this. I point you to an quick snippet to point you to the right direction. Here it is.

<?php
defined('_JEXEC') or die;
?>
<div class="latestnews">
<ul class="list-group list-group-flush">
  <?php foreach ($list as $item) : $image = json_decode($item->images); ?>
  <?php
    // most important part
    // context: 
    // for articles: com_content.article
    // for users: com_users.user
    // etc...
    $jcfields = FieldsHelper::getFields('com_content.article', $item, true);

    // bonus: custom fields by name
    // usage: $fields_by_name['name-of-field']->value
    $fields_by_name = \Joomla\Utilities\ArrayHelper::pivot($jcfields, 'name');

  ?>
  <li itemscope itemtype="https://schema.org/Article" class="list-group-item px-0" style="background-color:<?php echo $fields_by_name['article-favourite-color']->value; ?>">
     <?php if($image->image_intro != "") : ?>
        <a class="article-media" href="<?php echo $item->link; ?>" itemprop="url">
           <img class="card-img-top pb-2" src="<?php echo JURI::root().$image->image_intro; ?>" alt="<?php echo htmlspecialchars($image->image_fulltext_alt); ?>">
        </a>
     <?php endif; ?>
     <a class="article-title" href="<?php echo $item->link; ?>" itemprop="url">
        <span itemprop="name">
           <?php echo $item->title; ?>
        </span>
     </a>
  </li>
  <?php endforeach; ?>
  </ul>
</div>

This is the code I wrote a long time ago for a friend using mod_latest_news but hopefully It should point you on the right path to achieve what you want.

link to the snippet

EDIT 1

Hi, From what I understand you try to achieve, you should create an alternate layout for the URL custom field named "reglink" for example. You must place it in your frontend template at this location: /templates/yourfrontendtemplate/html/layouts/com_fields/field/reglink.php

Here is an example code you might add in this file

<?php
defined('_JEXEC') or die;
extract($displayData, EXTR_SKIP);

$value = $field->value;

if ($value == '')
{
  return;
}
?>
 <a href="<?php
     echo htmlspecialchars(JStringPunycode::urlToUTF8($value), 
     ENT_COMPAT,'UTF-8'); ?>" name="<?php
  echo $name; ?>" <?php
  echo !empty($class) ? ' class="' . $class . '"' : ''; ?> id="<?php
  echo $id; ?>"><?php echo 
  JText::_('LNG_URL_CUSTOM_FIELD_REGISTRATION_LINK'); ?></a>

LNG_URL_CUSTOM_FIELD_REGISTRATION_LINK is a language string I added for you so you can override the text of the link. You can create a language override to do this.

Once you created the alternate layout for the URL custom field. You must go to your admin area for your Joomla! site at this location https://example.com/administrator/index.php?option=com_fields&context=com_dpcalendar.event . You must replace example.com with your domain.

Then you create a custom field of type URL. The name should be "reglink". As you said in your question. Then you go to options tab and near the bottom choose automatic display "Do not display automatically" Then the important part to show the URL as a link, choose layout "reglink" (the same name of the file from the steps above). Save and close.

The next step is your module.

Here is the code that should work for you

<?php
  /**
   * @package    DPCalendar
   * @author     Digital Peak http://www.digital-peak.com
   * @copyright  Copyright (C) 2007 - 2019 Digital Peak. All rights 
     reserved.
   * @license    http://www.gnu.org/licenses/gpl.html GNU/GPL
   */
  defined('_JEXEC') or die();

   if (!$events) {
      echo JText::_('MOD_DPCALENDAR_UPCOMING_NO_EVENT_TEXT');

      return;
    }

    require JModuleHelper::getLayoutPath('mod_dpcalendar_upcoming', 
     '_scripts');
     ?>
     <div class="mod-dpcalendar-upcoming mod-dpcalendar-upcoming- 
       simple mod-dpcalendar-upcoming-<?php echo $module->id; ?>">
      <?php foreach ($groupedEvents as $groupHeading => $events) { ?>
      <?php if ($groupHeading) { ?>
        <div class="mod-dpcalendar-upcoming-simple__group">
        <p class="mod-dpcalendar-upcoming-simple__heading dp-group- 
          heading"><?php echo $groupHeading; ?></p>
     <?php } ?>
      <?php foreach ($events as $index => $event) { ?>
        <?php $startDate = $dateHelper->getDate($event->start_date, 
      $event->all_day); ?>

        <?php
        // most important part
         // context:
         // for articles: com_content.article
         // for users: com_users.user
         // for dpcalendar: com_dpcalendar.event
          $custom_fields_context = 'com_dpcalendar.event';
          $jcfields = FieldsHelper::getFields($custom_fields_context, 
          $event, true);

          // bonus: custom fields by name
          // usage: $fields_by_name['name-of-field']->value
           $fields_by_name = 
           \Joomla\Utilities\ArrayHelper::pivot($jcfields, 'name');

          ?>
            <div class="mod-dpcalendar-upcoming-simple__event">
            <div class="row">
                <div class="mod-dpcalendar-upcoming-simple__date col- 
           md-4 event-num">
                    <?php echo $dateHelper- 
                    >getDateStringFromEvent($event, $params- 
                    >get('date_format'), $params->get('time_format')); 
             ?>
                </div>
                <div class="mod-dpcalendar-upcoming- 
                simple__information col-md-8">
                    <a href="<?php echo $event->realUrl; ?>" 
              class="dp-event-url dp-link"><?php echo $event->title; ? 
            ></a>
                    <p><a href="<?php echo $event->realUrl; ?>" 
     class="dp-event-url dp-link more">More Info >></a>
                    <?php echo 
     FieldsHelper::render($custom_fields_context, null, array('field' 
      => $fields_by_name->reglink)); ?>
                    </p>
                    <?php if ($params->get('show_location') && 
      isset($event->locations) && $event->locations) { ?>
                        <?php foreach ($event->locations as $location) 
      { ?>
                            <span class="mod-dpcalendar-upcoming- 
      simple__location"
                                  data-latitude="<?php echo $location- 
      >latitude; ?>"
                                  data-longitude="<?php echo 
      $location->longitude; ?>"
                                  data-title="<?php echo $location- 
      >title; ?>">
                            <a href="<?php echo $router- 
      >getLocationRoute($location); ?>" class="dp-link">
                                <?php echo $location->title; ?>
                            </a>
                        </span>
                        <?php } ?>
                    <?php } ?>
                </div>
            </div> <!-- End of event row -->
            <?php if ($event->images->image_intro) { ?>
                <div class="mod-dpcalendar-upcoming- 
         simple__image">test
                    <figure class="dp-figure">
                        <img class="dp-image" src="<?php echo $event- 
          >images->image_intro; ?>"
                             alt="<?php echo $event->images- 
          >image_intro_alt; ?>">
                        <?php if ($event->images->image_intro_caption) 
          { ?>
                            <figcaption class="dp-figure__caption"><? 
           php echo $event->images->image_intro_caption; ?> 
         </figcaption>
                        <?php } ?>
                    </figure>
                </div>
            <?php } ?>
            <?php if ($params->get('show_booking', 1) && 
          \DPCalendar\Helper\Booking::openForBooking($event)) { ?>
                <a href="<?php echo $router- 
        >getBookingFormRouteFromEvent($event, $return); ?>" class="dp- 
        link dp-link_cta dp-button">
                    <?php echo $layoutHelper- 
        >renderLayout('block.icon', ['icon' => 
       \DPCalendar\HTML\Block\Icon::PLUS]); ?>
                    <?php echo $translator- 
       >translate('MOD_DPCALENDAR_UPCOMING_BOOK'); ?>
                </a>
            <?php } ?>
            <div class="mod-dpcalendar-upcoming-simple__description">
                <?php echo $event->truncatedDescription; ?>
            </div>
            <?php $displayData['event'] = $event; ?>
            <?php echo $layoutHelper->renderLayout('schema.event', 
           $displayData); ?>
        </div>
       <?php } ?>
       <?php if ($groupHeading) { ?>
          </div>
        <?php } ?>
      <?php } ?>
    </div>

Its mainly the code you provided but I added some important modifications commented for you so you can make it work or even as a guide.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.