Adding wrapper elements within a date format

Created on 1 March 2023, over 1 year ago
Updated 8 March 2024, 9 months ago

I am wondering if it's possible to add wrapper elements around individual components in a smart date formatter. For example, I would like to format a calendar page with the date in a large format on the side, and the month, year and time to the right. This will be much easier if I can put the date in it's own element or something similar.

I have tried escaping the characters like this, but it does not work.

\<\s\p\a\n\>\ j \<\\\s\p\a\n\>\ F, Y

Instead of wrapping the date in a it wraps the entire element in a span, and places an unescaped within the date.

Even if this did work, it does not seem like a very elegant solution. I'm wondering if there is some other way to go about this I could be overlooking. Any help or guidance would be appreciated.

💬 Support request
Status

Active

Version

3.7

Component

Code

Created by

🇺🇸United States srdtwc Skokie, IL

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @srdtwc
  • 🇨🇦Canada mandclu

    The Smart Date formatter does include a configuration option to "Add classes", which will add spans around the date and time values. Have you tried enabling that?

  • 🇺🇸United States srdtwc Skokie, IL

    I've tried that. It seems to add a span around the date and around the time, but not spans around the individual parts of the date like I would like. For example, I would like a span around the 10 in "10 March, 2023" here.

    I'm currently trying to do this with twig templates, which seems to be promising but the tradeoff seems to be losing a lot of the advanced features of smart date in the process, since I need to manually render all aspects of the date and time in the template and add my own logic for when to show the separator, etc.

  • 🇨🇦Canada mandclu

    You should be able to accomplish what you want using a preprocess function in your theme. By design Smart Date keeps its output as a render array, and IIRC even keeps the raw timestamp in the array, which should give you lots of flexibility to add extra wrappers to meet your needs.

  • Status changed to Needs review over 1 year ago
  • 🇮🇳India Meeni_Dhobale

    I tried to add wrapper element by using the preprocessor. I only added the wrapper for default formater.
    The output is as follows:

  • Status changed to Active over 1 year ago
  • 🇨🇦Canada mandclu

    Nice that you got it working. :-)

    That preprocessing code belongs in your theme, not in Smart Date, since it will only work with your date string.

  • 🇺🇸United States srdtwc Skokie, IL

    Thanks, this is helpful. I was able to get the patch above working by moving the code to my .theme file in hook_preprocess_time(). This is definitely getting me in the right direction.

    I'm not finding any documentation though on which theme hooks are available. I don't see "preprocess_time" anywhere in Drupal core or smart_date. Is there somewhere I should be looking to find which theme hooks are available?

    Thanks for your help!

  • 🇨🇦Canada mandclu

    Maybe what you're looking for is hook_preprocess_field?

  • 🇺🇸United States srdtwc Skokie, IL

    I ended up taking a slightly different approach:

    1) Changed the smart date format to only display the month and year (not the date)

    F, Y

    2) Used hook_preprocess_node in the .theme file to clone the smart_date field

        $variables['content']['field_smart_date2'] = $variables['content']['field_smart_date'];
        $variables['content']['field_smart_date2']['#field_name'] = 'field_smart_date2';
    // swap date items
        [$variables['content']['field_smart_date'], $variables['content']['field_smart_date2']] = [$variables['content']['field_smart_date2'], $variables['content']['field_smart_date']];
      }

    3) Created a twig template to change the output of this new cloned field to render the day

    field--node--field-smart-date2--event.html.twig

    <div class="smart-date--day-only">{{ items.0['content']['#value']|date('j')  }}</div>
    

    This results in an output that looks like this

    A little complicated, but sharing this in case others find this approach useful.

    Thanks for your help on this. I think we can close the issue.

  • 🇨🇦Canada mandclu

    Thanks for sharing what worked for you. This would be great material for a handbook page

  • 🇺🇸United States NicholasS

    I would love an official how to on how to do this, also in this same boat.

Production build 0.71.5 2024