Wednesday, April 23, 2025

Day 5: Making it Look Good - Theming and Basic Styling


Day 5, and it's time to make our Sitecore site look less like a collection of boxes and more like a real website! Today, I'm diving into theming and basic styling in SXA.

What I'm Learning Today:

  • SXA Themes: The Site's Skin. SXA uses themes to control the visual styling. There are default themes, and I'm learning how to apply them to my site. Themes contain CSS, JavaScript, and other assets. Get an overview of "Themes" within the SXA section of the Sitecore Documentation page: https://doc.sitecore.com/
  • Customizing Themes: The default themes are a good starting point, but most projects need customization. I'm looking into how to clone a theme and then modify the CSS and other assets to match a specific design. Search the Sitecore Documentation page for "Customize SXA Theme": https://doc.sitecore.com/
  • Scriban: Dynamic Rendering Power. Scriban is a templating language used within rendering variants for more advanced logic when displaying content. It looks like a way to add dynamic behavior to my components without writing full C# code for every little thing. Find information on "Scriban" within the SXA documentation on the Sitecore Documentation page: https://doc.sitecore.com/
  • Custom Components (A Glimpse): While SXA has a lot of components, sometimes you need something unique. I'm getting a basic understanding that you can create custom renderings using C# and integrate them into Sitecore. This is more advanced, but good to know for the future. Look for information on "Create a Rendering" on the Sitecore Documentation page: https://doc.sitecore.com/

My Day 5 Takeaways:

  • SXA themes provide a structured way to manage the visual styling of a Sitecore site.
  • Customizing themes involves working with CSS and other front-end assets within the Sitecore theme structure.
  • Scriban looks like a powerful tool for adding dynamic behavior to components directly within the Sitecore UI.
  • While SXA offers a lot, Sitecore's extensibility allows for creating fully custom components when needed.

Where to Go From Here:

This 5-day sprint has given me a solid foundation in Sitecore XM and SXA. My next steps are definitely going to be:

  • Deeper dive into Scriban and more complex rendering variant scenarios.
  • Exploring the world of custom component development.
  • Understanding data source configuration and how components get their content.
  • Learning about workflows and the content publishing process in Sitecore.
  • Engaging with the awesome Sitecore community!

Thanks for joining me on this learning journey! I hope this has been helpful. Remember, the Sitecore Documentation (https://doc.sitecore.com/) is your best friend as you continue to explore.


Happy learning!

#Sitecore #SXA #WebDevelopment #Learning #CMS

Day 4: Giving Content Structure - Data Templates and Architecture


Day 4 is all about understanding how content is organized and structured within Sitecore using data templates. This is the backbone of any good website.

What I'm Learning Today:

  • Data Templates: Defining Content Fields. Templates are the blueprints for our content. They define what fields each type of content item will have (e.g., a news article might need a headline, body, image, and author). Learning how to create and configure these is key: Explore the "Working with Templates" section on the Sitecore Documentation page: https://doc.sitecore.com/
  • Content Architecture: Planning for the Future. Just creating templates isn't enough. I need to think about how different content types relate to each other and how they'll be organized in the Content Tree. This is all about planning for a maintainable and scalable website. Search the Sitecore Documentation page for "Content Architecture" or "Content Strategy" for more insights: https://doc.sitecore.com/
  • Standard Values: Setting the Defaults. Standard values let you pre-populate fields in a template with default content. This saves content authors time and ensures consistency. Learn about "Standard Values" on the Sitecore Documentation page: https://doc.sitecore.com/
  • Information Architecture (IA): The User's Journey. While not strictly a Sitecore feature, I'm also thinking about how users will navigate the site and how content will be linked. A well-planned IA is crucial for a good user experience.

My Day 4 Takeaways:

  • Data templates are the fundamental building blocks for defining content structure in Sitecore.
  • A well-thought-out content architecture is essential for a manageable and scalable website.
  • Standard values are a neat way to improve the content authoring experience and maintain consistency.
  • Thinking about the user's journey (IA) is just as important as the technical content structure.

Next Steps: Tomorrow, I will shift my focus to the visual layer, exploring SXA themes and how to customize the website's look and feel. I'll also get a basic introduction to Scriban for more advanced rendering customizations.

Follow along: https://learning.sitecore.com/learn/learning_plan/view/26/sitecore-experience-accelerator-sxa-collection.

Day 3: Playing with LEGOs - SXA Components and the Grid


Alright, Day 3 and I'm finally in the Experience Editor, playing with SXA! It feels like building with LEGO, but for websites.

What I'm Learning Today:

  • The SXA Toolbox: A Treasure Trove! Wow, there's a whole library of pre-built components I can just drag and drop onto the page. Text, Image, Navigation, Forms, it's all there! This will definitely speed things up. You can find an overview of SXA components on the Sitecore Documentation page: https://doc.sitecore.com/
  • The 12-Column Grid: Layout Power! SXA uses a responsive 12-column grid system. It's all about dividing the page into these columns and placing components within them to create different layouts that adapt to various screen sizes. The "Layout" tab in the Experience Editor is where you control this. Learn more about the SXA Grid System on the Sitecore Documentation page: https://doc.sitecore.com/
  • Rendering Variants: Component Flexibility. This is a cool concept. Instead of writing code to display a component differently in various situations, rendering variants let you define different HTML structures and data mappings right in the Sitecore UI. Check out the "Rendering Variants" section on the Sitecore Documentation page: https://doc.sitecore.com/
  • Partial Designs: Reusable Sections. These are like pre-built chunks of layouts and components (like a header or footer) that you can reuse across multiple pages. Huge time-saver! More info on "Partial Designs" can be found on the Sitecore Documentation page: https://doc.sitecore.com/

My Day 3 Takeaways:

  • The SXA Toolbox is packed with useful, ready-to-go components.
  • Understanding the grid system is crucial for creating flexible and responsive layouts without writing extensive custom CSS.
  • Rendering variants provide a powerful way to customize component presentation without requiring code changes for every minor adjustment.
  • Partial designs are going to be my best friend for creating consistent site structures.

Next Steps: Tomorrow, I'm digging into the data side of things – how content is structured using data templates and how it all comes together.

Follow along: https://learning.sitecore.com/learn/learning_plan/view/26/sitecore-experience-accelerator-sxa-collection.

Day 2: Getting My Hands Dirty - Setting Up Shop

 


Day 2 is all about getting a local Sitecore development environment up and running. This can be a bit of a rite of passage for Sitecore developers, so let's see how it goes!

What I'm Learning Today:

  • Local Installation (The Traditional Route): I'm going the traditional route for now, using the Sitecore Install Assistant (SIA). It looks like there are prerequisites like .NET Framework, ASP.NET Core Hosting Bundle, and SQL Server. The official installation guide seems pretty comprehensive (and necessary!): Find the installation guide for your specific Sitecore version on the main Sitecore Documentation page: https://doc.sitecore.com/
  • Key Tools - Initial Setup:
    • Sitecore CLI: Installed this using the .NET CLI. Seems like it's going to be my go-to for tasks like serializing items and deploying code. Get started with Sitecore CLI on the Sitecore Documentation page: https://doc.sitecore.com/
    • Sitecore for Visual Studio: Just installed this extension in Visual Studio. It adds Sitecore project templates and helps with connecting to my local instance. Look for information on "Sitecore Developer Tools" or "Sitecore for Visual Studio" on the Sitecore Documentation page: https://doc.sitecore.com/

My Day 2 Takeaways:

  • Setting up a local Sitecore instance can be a bit involved, so following the official documentation closely is key. Patience is definitely a virtue here!
  • Sitecore CLI looks like a powerful tool for automating Sitecore tasks.
  • The Visual Studio extension appears to make development within my familiar IDE much smoother.

Next Steps: Tomorrow, the fun begins! I'm finally going to start playing with SXA components in the Experience Editor. Let's see what these pre-built goodies can do!

Follow along: https://learning.sitecore.com/learn/learning_plan/view/50/xm-cloud-for-jss-headless-developers.

Move to day 3

Day 1: Hello Sitecore XM & SXA - First Impressions

 


Okay, Day 1. Time to demystify Sitecore XM and SXA. I've heard they're a big deal in the web development world, so let's see what the hype is all about.

What I'm Learning Today:

  • Sitecore XM: The Content Powerhouse. From what I gather, Sitecore XM is the core CMS. It's not just a place to store text and images; it's a system for managing the entire lifecycle of web content, featuring workflows and collaboration tools. Think of it as the structured brain behind a website.
  • Sitecore SXA: The Developer's Toolkit. SXA is the cool kid on the block for us developers. It's a layer on top of XM that provides a ton of pre-built components, templates, and even themes. The promise? Faster development and more reusability. Sounds like music to my ears!
  • Key Concepts - My Initial Grasp:
    • Templates: These are like content blueprints. Imagine defining the fields for a blog post (title, body, author, date). That's what templates do. Explore the "Working with Templates" section on the Sitecore Documentation page: https://doc.sitecore.com/
    • Layouts: The structure of a webpage – where different elements go. Search for "Layouts" on the Sitecore Documentation page: https://doc.sitecore.com/
    • Renderings/Components: Reusable UI bits that display content or add functionality. SXA boasts a big library! Look for "Renderings" or "Components" on the Sitecore Documentation page: https://doc.sitecore.com/
    • Themes: Styling – the look and feel of the site. Find information on "Themes" within the SXA section of the Sitecore Documentation page: https://doc.sitecore.com/
    • Experience Editor: The visual editor for content folks to build pages. Understanding this is key for building components they'll love. Learn about the "Experience Editor" on the Sitecore Documentation page: https://doc.sitecore.com/

My Day 1 Takeaways:

  • Sitecore XM is a robust CMS, and SXA is the framework that aims to make our development lives easier.
  • The core concepts of templates, layouts, and components appear fundamental to the structure and display of content.
  • The Experience Editor is where the content magic happens for non-developers.

Next Steps: Tomorrow, I'm tackling setting up a local development environment. This is crucial for actually getting my hands dirty. Wish me luck!

Follow along: https://learning.sitecore.com/learn/learning_plan/view/51/xm-cloud-for-net-headless-developers.

Move To Day 2 

Monday, November 4, 2024

🍽️ Welcome to Sitecore Content Hub DAM Events! 🍽️ Today’s Special Menu: The Unexpected Events

 


Welcome, dear diners, to a most unique tasting experience! Our chef, Sitecore Content Hub DAM, has prepared a surprise menu where every dish is an “event” you never expected but might just love. Take a seat, enjoy, and let’s dive into the flavors of digital unpredictability. Bon appétit!

Starters

  • ENTITY_CREATED
    A Surprise Starter! – A new entity appears, freshly whipped up and served with a dash of spontaneity. Perfect for those who love a little mystery to begin.

  • ENTITY_DELETED
    Here One Moment, Gone the Next – A fleeting delicacy, savored briefly before it disappears forever. Was it there at all? Only your memory knows.

  • OPTION_LIST_CREATED
    Menu Expansion – A spontaneous assortment of options. Customize your experience with an array of unexpected choices!

  • APPLY_AUDIT_QUERY
    Detective’s Delight – A light starter to whet your appetite for insights. Dig deep and uncover the hidden flavors within each byte.

Mains

  • ENTITY_SAVED
    The “Safe Bet” Special – This classic comes securely served and saved, ensuring a delightful experience with no risks on the side.

  • REFRESH_SEARCH
    New Discoveries – A refreshing take on familiar flavors. Every refresh reveals a new twist, leaving you curious for what’s next.

  • REDUX_ERROR
    The Oops Platter – An unexpected, sometimes baffling blend of ingredients that will make you wonder, “Was this supposed to happen?” But hey, it adds a bit of character to the meal!

  • END_OF_PAGE_REACHED
    The Final Act – The ultimate course, served right at the end. Perfect for those who believe the best things are worth waiting (and scrolling) for.

Sides

  • COMPONENT_COPIED
    Cloning Perfection – A double serving of your favorite side, recreated with precision.

  • COMPONENT_PASTED
    Perfect Placement – Just the right addition to complement any meal, carefully placed for balance.

  • SELECTION_CHANGED
    New Tastes – A shift in flavors, a pivot in selection. Sides that adapt to your changing preferences with a smile.

Desserts

  • ERROR
    The Unplanned Surprise – Not on the menu, but a dish you’ll remember. Mistakes, after all, make for the most memorable bites.

  • CLOSE_INLINE_PREVIEW
    Preview’s Last Glimpse – Just a small taste, enough to intrigue before it fades away. Perfect for the curious diner who loves a tease.

  • INSERT_IMAGE
    Picture Perfect Finish – A beautiful visual dessert, carefully plated to end your meal with just the right touch of style.

  • INSERT_VIDEO
    Action Finale – A lively video dessert, bringing energy and rhythm to the end of your meal. Enjoy the show!

Our dishes may surprise and confound, but that’s the beauty of the experience at Sitecore Content Hub DAM. Thank you for dining with us, where each meal is an adventure and each event is a dish to remember.

Bon appétit!

Wednesday, September 25, 2024

"Sort by" or "Why Are We Not on the Menu?": A Story of Divs, Dropdowns, and Dropped Expectations

Imagine walking into our world-famous Restaurant of Mistaken Orders, where the charm lies not in what you ordered, but what you end up with. You ask for a refreshing iced tea, and what do you get? Spaghetti Bolognese. You request a slice of cake, and a plate of sushi arrives. The unpredictability is part of the charm. But what if the unpredictability spilled over into technology, where we expect things to work as planned? Welcome to the wild world of “Sort by”—where things aren't quite what they seem, much like the orders at our beloved restaurant.

The Problem: "Sort by" – A Div Masquerading as a Dropdown

At the Restaurant of Mistaken Orders, we love a good surprise. But when it comes to coding, we’d appreciate a little more... predictability. So, let’s talk about the curious case of our Sort by feature, which is acting more like a rogue waiter who just won’t bring you what you asked for.

You see, "Sort by" looks like a button. It sits there in the interface, all smug, waiting for you to click it and organize your assets. But plot twist—it's not a button at all. It's a div! Yes, a div that wants to be a dropdown, but doesn't behave like one. And, as anyone who has worked with React will tell you, a div pretending to be a button is like asking for a Caesar salad and getting a chocolate soufflé. Oddly delightful in some contexts, but entirely unhelpful when you just want your greens.

Reverse Sorting and Refresh Buttons: The True Buttons

While the "Sort by" dropdown is over in its corner doing whatever it is divs do, the “Reverse Sort by” and “Refresh” buttons are behaving like proper restaurant staff. These two are actual buttons! You can click them, interact with them, and they’ll flip your A-Z sort to Z-A like a waiter finally getting your dessert order correct (on the third try, naturally). They do their job. They understand their place in the hierarchy of web components.

But “Sort by”? Nope. That’s our rebellious chef who refuses to make an omelette because "eggs are just too mainstream." And this chef has taken a vow of silence. You can click it all you want, but it just won’t respond.

Why Can’t I Click It?

Now, here’s where things get quirky—just like how, at our restaurant, sometimes the soup shows up without a spoon. Normally, you can attach click events to divs. It's no big deal. But in this case, when you try to attach a click event to the Sort by div, nothing happens. It’s like trying to get a table by waving frantically at the maître d’—completely ignored.

What makes matters worse? The sub-menu from the dropdown is generated on the fly. That means it’s not sitting there in the DOM waiting to be poked and prodded by eager developers like us. No, no, that would be too easy. It’s only created when someone manually interacts with it. Like a ghost menu that only appears when you whisper the secret password.

But Why Do We Even Want to Click It?

Good question! You might be wondering, why all this fuss over clicking something that doesn’t want to be clicked? Well, it’s because we’ve got an AI assistant that needs to help sort the page based on user commands. Someone might say, “Hey, sort my assets by title!” and we want our trusty assistant to do just that. But instead of giving the AI the nice, neat power to sort via the search API, which refuses to cooperate, we’re stuck trying to simulate a click.

It would be as simple as pressing a button—if only that button were an actual button and not a div in disguise.

The Not-So-Tasty Solution

So, what's the workaround? How do we deal with a rogue div that won’t let us simulate a click? Well, my solution was to update the session that contains the sorting information and then refresh the page. You know, like how at our restaurant, if you really want to get what you asked for, you just order something else entirely and hope for the best.

It’s not elegant. It’s like serving soup in a coffee cup—it technically works, but no one’s thrilled about it.

Why Isn't It a Real Dropdown or Button?

The burning question that keeps us up at night (besides “Did I accidentally double-book that reservation?”) is: Why isn’t "Sort by" a real dropdown or button? If it were, life would be simpler, and our AI assistant could gracefully handle sorting duties. But instead, we’re left with this div-shaped puzzle that, like a misplaced order of anchovy ice cream, leaves us scratching our heads.

Would it have been too easy to just use a button? A standard dropdown? Something with a little more... clickability? Perhaps. But at the Restaurant of Mistaken Orders, we know that sometimes things get a little jumbled up. And in this case, “Sort by” is serving us a confusing, featureless div where there should be a nice, interactive button.

The Final Word

In conclusion, working with this quirky div reminds me of dining at our beloved restaurant. You never quite know what you’re going to get, and sometimes, the solution isn’t what you wanted—but it’s what you’ve got to work with. We’ll make do with session updates and page refreshes, but deep down, we’ll always long for a day when “Sort by” is finally a proper button, ready to be clicked at will.

Until then, we’ll just embrace the chaos—both in our code and on our plates. After all, if everything worked perfectly, it just wouldn’t be the Restaurant of Mistaken Orders, now would it?

Sunday, August 18, 2024

The Adventures of Clutter Slayer: From VW Up! to AI-Powered App



Ten years ago, in a land of sausages and beer (yes, I’m talking about Germany), I embarked on a journey that would change my life. I wasn’t scaling mountains or exploring uncharted territories; no, my adventure involved something much more daunting: fitting an entire life, plus that of my boyfriend, into a Volkswagen Up!. For those unfamiliar, a VW Up! is essentially a stylish shoebox on wheels, so imagine trying to squeeze all your worldly possessions into it. Spoiler: it involved a lot of decluttering. And thus, the seed of a brilliant idea was planted.

As I painstakingly categorized, boxed, and labeled every single item I owned (to avoid losing that one stray sock or charger), I had a lightbulb moment. Wouldn’t it be cool if there was an app that helped you keep track of where everything was stored? An app that would stop you from tearing your hair out trying to remember whether the winter blankets were in Box A, in storage, or currently doubling as your cat’s favorite hideout?

Now, rewind ten years to when this idea first hit me. Back then, the App Store wasn’t exactly swarming with decluttering tools. I mean, Marie Kondo wasn’t yet a household name, and most people were still hoarding phone chargers like they were gold bars. So, I rolled up my sleeves, brushed off my coding skills, and built a website called Stooxs.com (don’t ask me about the name; I was going through a phase). It was a modest little site, designed to be mobile-friendly at a time when “mobile-friendly” usually meant “barely usable on a touchscreen.”

Stooxs worked well enough for a while. It allowed users to create virtual boxes, assign items to them, and track everything with labels. People seemed to appreciate having a digital catalog of their storage life, and I was pretty pleased with it. But let’s be honest: technology evolves, and so did my vision. Fast-forward to today’s world, where AI is practically doing everything except making your morning coffee (and give it time, it’ll get there).

The Birth of Clutter Slayer

Enter Clutter Slayer, my shiny new app. This time, I went all-in and built a fully native iOS app because, let’s face it, trying to navigate a website that just barely fits on a phone screen isn’t ideal for anyone. Plus, Stooxs.com was feeling a little dated. The new app would do everything the website did and more—but with AI-powered magic sprinkled on top.

You see, Clutter Slayer isn’t just your ordinary storage organizer. The app helps you create virtual boxes, but here’s where it gets smart. Using AI object recognition, it can identify items as you add them. Gone are the days of typing out long lists of “winter boots, old VHS tapes, and that weird lamp your grandma gave you.” Just snap a picture, and the app does its best Sherlock Holmes impression by guessing what’s in the box.

Of course, the AI is still learning, so it doesn’t always get it right. I’ll admit, during testing, it identified a potato masher as “medieval weaponry” (not entirely inaccurate if you’re creative). But that’s where manual entry comes in handy—you can always override the AI’s enthusiastic misidentifications. Once everything’s logged, you can print out QR codes to stick on your actual boxes. Next time you’re knee-deep in the attic trying to find where you stashed the Christmas lights, just scan the code, and boom—you’ve got an instant inventory.

Bells, Whistles, and a Few Dead Ends

When I first started building Clutter Slayer, I was like a kid in a candy store. The possibilities seemed endless, and I couldn’t resist adding every cool feature I could think of. Voice commands? Check. AI-powered talking assistant? Double check. At one point, you could say, “Hey Clutter Slayer, where did I put my waffle iron?” and the app would actually answer (with more attitude than I intended). It was hilarious but also wildly unnecessary.

I quickly realized that all these bells and whistles were just cluttering (ironically) the app’s main purpose. The core idea was to simplify organization, not turn it into a sci-fi experience where your app feels like it’s judging your life choices. So, I did what any good developer would do: I stripped out the fluff. Voice commands and chatty AI were cool in theory, but honestly, who wants to have a conversation with their storage app? Maybe one day, if there’s enough demand, I’ll bring those features back—after all, who wouldn’t want an AI best friend that can tell you exactly where your vintage action figures are?

The Road Ahead: From Vision to Reality

Building Clutter Slayer wasn’t all smooth sailing, of course. There were moments when I was ready to throw in the towel, particularly when debugging AI features that seemed determined to classify everything as “miscellaneous kitchen gadgets.” But in the end, it all came together. The app is live on the App Store, and you can even check out the accompanying website, clutterslayer.app.

So, what’s next? My plan is to keep improving Clutter Slayer, taking user feedback into account and refining the app’s capabilities. Perhaps one day, it’ll be smart enough to recommend what items you should declutter altogether (goodbye, that hideous lamp). For now, I’m just excited to have brought this decade-old idea to life, all thanks to a random move from the Netherlands to Germany, a tiny Volkswagen Up!, and a desperate need to stay organized.

If you’ve ever struggled with clutter (and let’s be real, who hasn’t?), give Clutter Slayer a try. It’s not just about managing your storage—it’s about reclaiming your space, one box at a time. And who knows? Maybe in the process, you’ll finally find that long-lost charger.

Download Clutter Slayer from the App Store here and visit the website at clutterslayer.app. Because life’s too short to keep losing things in boxes.


There you have it! The journey of Clutter Slayer, from a tiny car packed to the brim to an app that’s ready to help the world conquer clutter. And if this story teaches you anything, it’s that sometimes the best ideas come from life’s smallest inconveniences—like trying to fit your entire life into a VW Up!.

Wednesday, July 31, 2024

The Not-So-Flexible Validation Component: A Comedy of Errors in Sitecore Content Hub


Ah, the summer of 2024—a time for sun, fun, and the release of the much-anticipated Validation component in Sitecore Content Hub. Promising to be the central hub for all your validation needs, this component aimed to gather all validation rules in one place, ensuring data integrity and consistency across your digital assets. We were all set for a smooth ride, expecting a component as flexible as a yoga master. But, as it turns out, this component is more like that one friend who insists they’re flexible but can barely touch their toes.

In this exploration, we will dive into the nuances of the Validation component, exploring its setup, configuration, and—let's be honest—its rather surprising limitations.

Default Configuration: The Basics

To start, we embraced the default configuration, which, in theory, should be a breeze:

{ "definitionName": "M.Asset" }

This simple setup was supposed to be our ticket to hassle-free validation. Spoiler alert: it was anything but.

Configuration Steps: Setting the Stage

Add the Validation Component to Your Page

First, we dutifully placed the Validation component on our desired page within Sitecore Content Hub. Like an eager host setting up for a party, we expected this component to handle all our validation needs with the grace of a seasoned maître d'. Instead, it felt more like hiring a bouncer who’s really good at pointing out problems but not so great at fixing them.

Always Visible Setting: Not So Always

The component features an "always visible" option, presumably to keep validation messages on display at all times. In reality, this setting is more like that one co-worker who’s always around when you don’t need them and mysteriously absent when you do. Despite setting it to true, validation messages only pop up during edit and save operations. So much for always being visible!

Handling Validation Messages: A Visual Buffet

In an unexpected twist, both new and old validation messages decided to show up, occupying the bottom right corner like uninvited guests at a dinner party. There's no clear method to send the old messages packing, leaving us with a cluttered interface that’s anything but user-friendly.

Validating Fields: The Tale of Unmet Expectations

We thought we’d get fancy and try validating non-mandatory fields or setting restrictions on mandatory ones. For instance, limiting the Title field to a maximum of five characters seemed like a simple enough task:

{ "definitionName": "M.Asset", "rules": [ { "fieldName": "Title", "validationType": "TextLength", "parameters": { "maxLength": 5, "errorMessage": "Title should not exceed 5 characters." } } ] }

The result? Crickets. Nada. Zilch. It turns out this component is about as responsive as a magic 8-ball that only says, “Ask again later.” We can only assume the documentation is missing a crucial piece or the component itself is still finding its way.

Removing All Settings: The Naked Truth

For a truly enlightening experience, we stripped the component down to its bare essentials, leaving an empty configuration:

{}

Amazingly, even with no settings, the component still insisted on validating mandatory fields on asset details. It’s like the one guest who won’t leave even after you’ve turned off the lights and locked the doors. Clearly, there are some default behaviors at play here, whether we like it or not.

Conclusion: A Not-So-Flexible Friend

In our journey through the initial setup and exploration of the new Validation component in Sitecore Content Hub DAM, our key takeaways? The component does not add anything useful for us, and we'd recommend steering clear for now.

Key Observations:

  1. Visibility: The "Always Visible" setting isn’t reliable.
  2. Validation Messages: Old and new messages coexist, cluttering the interface.
  3. Field Validations: Attempts to validate fields or set restrictions have been fruitless, likely due to incomplete documentation or implementation.

Sitecore has confirmed via email that this component is not as configurable as we'd hoped. It’s more of a passive observer, merely collecting and listing errors in one central place.

Future Steps: Navigating the Road Ahead

  • Documentation: Keep an eye out for updates or more comprehensive documentation from Sitecore.
  • Feedback: We've provided feedback on the documentation page and emailed the relevant contacts, hoping for some improvements.
  • Information: For the latest details, check out Sitecore's documentation.

In the end, the Validation component might not be the flexible, all-knowing solution we anticipated. But hey, sometimes you need a few unexpected surprises to keep things interesting—or at least to give you a good story to tell.

Wednesday, July 10, 2024

Serving Up Smart Data: How Our Restaurant of Mistaken Orders Got a Tech Makeover

Hey there, food lovers and tech enthusiasts! Today, we're dishing out a story that's as satisfying as our famous "Oops, I Dropped the Spaghetti" special. Gather 'round as we spill the beans on how our quirky little Restaurant of Mistaken Orders got a high-tech boost that would make even the most seasoned Silicon Valley geeks say, "I'll have what they're having!"

Picture this: You're sitting at one of our wobbly tables (we keep them that way on purpose, promise!), and you're curious about our menu's history. Wouldn't it be neat if our waiter could instantly tell you how many times the "Upside-Down Pizza" has been ordered in the last month? Well, now they can, thanks to a little bit of AI magic and some fancy database work!

We've cooked up a system that lets our staff query our restaurant database faster than you can say "accidental anchovy appetizer." Here's the secret sauce:

  1. We use a super-smart AI called ChatGPT to translate regular human questions into database-speak (that's SQL for you tech-savvy folks).
  2. We've got a special recipe (aka a prompt) that we feed to ChatGPT. This recipe includes our menu items, table layouts, and even our staff's favorite mistakes. It's like giving the AI a crash course in "Restaurant of Mistaken Orders 101."
  3. Once ChatGPT whips up the SQL query, we double-check it faster than our chefs check for eggshells in the "Surprise Omelet." We do this both in our snazzy React app and in our Azure functions (that's cloud stuff, for those who prefer their tech terms sunny-side up).

Now, you might be wondering, "Why all this fuss over SQL?" Well, let me tell you, SQL might be as old as our "Vintage Veggie Surprise," but it's still the go-to language for data processing. In fact, some smart folks in lab coats (data scientists, they call themselves) spend 40-80% of their time crafting SQL queries by hand! That's like kneading dough for hours when you could use a mixer!

But here's where it gets really exciting: by using AI to translate regular language into SQL, we're not just making our waitstaff's lives easier. We're potentially putting the power of data analysis into everyone's hands! It's like we're creating the TikTok of the data world – suddenly, everyone can be a creator (or in our case, a data chef)!

Now, you might be thinking, "Isn't letting AI mess with your database like letting a cat loose in the kitchen?" Fear not! We've got more safety measures than a bulk order of hair nets:

  1. ChatGPT is trained to keep the queries as safe as our "Definitely Not Ghost Pepper" sauce (spoiler: it's mild).
  2. Our React app gives the query a once-over, making sure it's not trying any funny business.
  3. Our Azure functions give it another check, just to be extra sure. It's like having three health inspectors instead of one!

And here's the cherry on top: our database is read-only. That means the AI can look at the menu all day long, but it can't add "Bug Surprise" as the dish of the day.

But wait, there's more! We've learned from the tech gurus that fine-tuning and prompt engineering are key ingredients in this AI soup. It's not just about throwing information at the AI and hoping for the best. We've carefully seasoned our prompts with just the right amount of:

  • Schema information (like a map of our menu)
  • Constraints (no mixing desserts with appetizers!)
  • Query examples (showing how we've mixed up orders in the past)
  • Semantic details (explaining why we call it the "Upside-Down Pizza")

Schema information example: ${databaseSchema}

export const databaseSchema = `
Table: adaptation_regions
Columns:
- region (nvarchar)
- market (nvarchar)
- id (int)
Keys:
- PRIMARY KEY (id)

Table: approver_groups
Columns:
- id (int)
- identifier (varchar)
- taxonomy_name (nvarchar)
- taxonomy_label (nvarchar)
- created_on (datetime2)
- modified_on (datetime2)
Keys:
- PRIMARY KEY (id) `;

Query example

export const getSqlCountPrompt = (input: string, messagesForAI: any[], limitTheAmountOfRowsTo: number = 5): string => {
const instruction = `
Generate a safe Azure SQL-compatible SELECT statement to retrieve detailed information about a specific item based on this request: "${input}"

Requirements:
- Write an optimized SQL SELECT query to count specific records as per the user request "${input}".
- Use explicit table aliases and prefix column names to avoid ambiguity.
- Use 'SELECT TOP (${limitTheAmountOfRowsTo})' along with an 'ORDER BY' clause to limit the number of rows returned.
- Ensure all columns in the ORDER BY clause are either in the SELECT clause or are part of an aggregate function.
- If GROUP BY is used, ensure all non-aggregated columns in the SELECT clause are included in the GROUP BY clause.
- For ratio comparisons like width/height, use appropriate WHERE clause conditions with explicit data type casting.
- For boolean values, use proper SQL syntax for true/false checks.
- Ensure that facet values are correctly associated with their corresponding columns, not interpreted as different data types like extensions.
- Only output a SELECT statement. Do not include any other SQL commands, comments, or formatting.
- Always include approved assets only in the select statement.

Example Queries:
- Example 1: SELECT COUNT(*) AS TotalAdaptations FROM assets WHERE creation_type = 'Adaptation';
- Example 2: SELECT COUNT(*) AS TotalMasters FROM assets WHERE creation_type = 'Master';
- Example 3: SELECT COUNT(t1.columnName) AS CountColumnName FROM TableName AS t1 JOIN AnotherTable AS t2 ON t1.commonColumn = t2.commonColumn;
- Example 4: SELECT COUNT(*) AS AssetCount FROM assets AS psa WHERE psa.creation_type = 'master' AND CAST(psa.width AS float) / CAST(psa.height AS float) = 16.0 / 9 AND psa.universal_retail_use = 1;
- Example 5: SELECT asset_id, COUNT(*) AS DownloadCount FROM asset_downloads GROUP BY asset_id ORDER BY DownloadCount DESC;

Note:
- Construct the SQL query using safe practices. Do not concatenate user inputs directly into the query. Use parameterized queries or safely escaped user inputs.
- Replace TableName, AnotherTable, columnName, and commonColumn with actual table and column names based on the database schema.
- Database Schema TABLE_NAME,COLUMNS,KEYS:
- ${databaseSchema}
`;

return `${instruction}`;
}


With all these techniques, we're seeing accuracy rates that would make even the most precise chef jealous. It's like we've solved the "how to make the perfect soufflé" of the data world!

So, next time you're at the Restaurant of Mistaken Orders and your waiter seems to know everything about our mixed-up menu history, you'll know it's not just stellar memory – it's our AI-powered secret weapon!

Remember, folks: this is just a taste of what's possible. We're not saying every restaurant needs to go full robot (though we are working on a "Robo-Waiter Who Always Gets Your Order Wrong" for laughs). But a sprinkle of tech here and there? That's the perfect recipe for a dining experience that's as entertaining as it is delicious.

Now, if you'll excuse me, I need to go ask our AI how many times we've accidentally served the napkins instead of the crepes. Bon appétit and happy querying!

Wednesday, June 5, 2024

Sitecore Content Hub Dam: A Fun Dive into Automated File Handling with Sitecore Content Hub and Azure Functions!


Welcome back to another thrilling installment in our journey of Sitecore Content Hub DAM (Digital Asset Management) automation! If you joined us in our last episode, we took a delicious bite into how to
move assets into the Sitecore Content Hub DAM with Azure storage containers. Now, we're here to sprinkle some extra seasoning on that recipe by automating the addition of correct headers and updating those all-important external component links. Picture this like adding the perfect garnish to an already mouth-watering dish!

Setting the Table: Recap from Our Last Meal

Previously, we explored the basics of uploading assets built using React Vite.js to an Azure storage container. The main course involved understanding how these assets could be moved seamlessly into the Sitecore Content Hub DAM, ensuring everything was neatly organized and easily accessible. But, as any great chef knows, it's not just about having the ingredients; it's about how you use them!

Today’s Special: Full Automation with Azure Functions

In this follow-up, we're diving deeper into the kitchen to see how automation can take our asset management to a Michelin-star level. Here’s the secret sauce: we’re going to automate the addition of the correct headers to our files and update the external component links in the Sitecore Content Hub DAM. Let’s break down this recipe step-by-step.

Ingredients

  • Azure Storage Account: Where your .js.gz files will be uploaded.
  • Azure Functions: Our automation tool to handle events and update headers and links.
  • Sitecore Content Hub DAM: The final destination for our beautifully prepared assets.
  • React Vite.js: Our asset generator.

The Automation Recipe

Step 1: Uploading the File

When you upload your .js.gz file (let's say it's named tasty-script.js.gz), it lands in the Azure storage container like a fresh ingredient in your pantry.

Step 2: Trigger the Azure Function

Our Azure Function, H_HandleBlobCreatedOrUpdated, is like a sous-chef that springs into action as soon as the file hits the container. Here’s what happens next:

  1. Event Detection: The function listens for the blob created event.
  2. Setting the Table: It sets the appropriate headers (Content-Type, Content-Encoding, and Cache-Control) to ensure our file is served just right.

Step 3: Update External Component Links

Once our headers are perfectly set, it’s time to update the links. Think of this as plating your dish and adding that final drizzle of sauce.

  1. Generate a Unique Version Identifier: This ensures that every time a new file version is uploaded, it doesn’t get mixed up with the old ones. We use a random identifier like 3e21a59a to make sure each serving is unique and fresh.
  2. Update Links in Sitecore Content Hub: The function then goes on a hunt through the Sitecore Content Hub, finding any references to the old file and updating them with the new version. It’s like making sure every guest at the restaurant gets the latest and greatest dish.

Here’s a Slice of the Code

Let’s take a peek at our master recipe: github.com


The Magic Behind the Scenes

So, what's the big deal about adding headers and updating links? Let's put it in restaurant terms. Imagine you're running a bustling kitchen. Each new dish (file) needs to be prepared just right before it reaches the dining room (your users). The headers are like the finishing touches - the perfect garnish, the right temperature. Without them, the dish might not be as appealing or could even be spoiled by the time it reaches the table.

Now, updating the external component link is like updating your menu. Every time you make a slight improvement to a recipe, you want to ensure your menu reflects the latest version. Otherwise, your customers might order something that no longer exists or get a previous version that doesn't showcase your culinary advancements.

Benefits of Full Automation Flow

1. Consistency and Accuracy:

  • Automation ensures that every file uploaded gets the exact headers and metadata it needs. No more manual mistakes or missed steps!

2. Time Savings:

  • Automating these processes means your team spends less time on repetitive tasks and more time on what really matters – creating great content.

3. Improved Performance:

  • Properly set headers can improve your site's performance by enabling efficient caching and ensuring that files are served correctly.

4. Seamless Updates:

  • Automatically updating links in the Sitecore Content Hub ensures that users always access the latest version of your files. This reduces the risk of broken links or outdated content.

The Complete Journey

Here’s a quick recap of the automation journey:

  1. Upload File: A new .js.gz file is built using React Vite.js and uploaded to an Azure storage container.
  2. Trigger Azure Function: The Azure Function detects the upload, sets the appropriate headers, and updates the metadata.
  3. Update Sitecore Content Hub: The function then updates the external component link in the Sitecore Content Hub to ensure the latest version is always available.

Why This Matters

In the digital world, ensuring your assets are always up-to-date and served correctly is crucial. This automation flow not only simplifies the process but also guarantees consistency and reliability. It's like having a top-notch kitchen where every dish is prepared perfectly and always updated with the latest recipe tweaks, ensuring your diners get the best experience every time.

What's Next?

Feeling inspired to take your content management to the next level? Try implementing this automation flow in your own projects and see the difference it makes. Stay tuned for more exciting tips and tricks as we continue to explore the delicious world of Sitecore Content Hub DAM automation!

Join the Conversation

Have you implemented similar automation in your workflows? Share your experiences and insights in the comments below. Let’s learn and grow together as we cook up the best digital experiences!

Tuesday, June 4, 2024

Sitecore Content Hub DAM - Moving External Components to Azure: A Recipe for Simplified Deployments


Welcome to the "Restaurant of Mistaken Orders" blog, where we serve up tech tips with a side of humor! Today, we're diving into a deliciously simple way to manage your external React components by moving them to Azure Storage. This will make your deployments as smooth as a perfectly cooked soufflé. So, grab your chef's hat, and let's get cooking!

Why Move to Azure?

Currently, we store our external component (React) code as portal components in Sitecore Content Hub DAM. Every time we have a release, we need to upload new versions to the portal assets and generate new public links. This process is as tedious as peeling a hundred potatoes by hand. To make deployments easier, we're moving our external component files to Azure. By having one SAS profile for all files in the container, we only need to upload new files to Azure during the release. A script will trigger changes, updating the public link in Content Hub with a caching parameter, not the complete URL. Voilà, deployment made easy!

Step-by-Step Guide to Azure Storage

1. Uploading Your .js.gz and .css.gz Files

First, let's upload our gzipped JavaScript and CSS files to Azure Storage.


For JavaScript Files:

  1. Upload the .js.gz File:
    • Upload your gzipped JavaScript file to the content-hub-external-components container in Azure Storage.
  2. Set Properties:
    • Open the file in Azure Storage Explorer or the Azure Portal.
    • Set the Content-Type to application/javascript.
    • Set the Content-Encoding to gzip.

For CSS Files:

  1. Upload the .css.gz File:
    • Upload your gzipped CSS file to the content-hub-external-components container in Azure Storage.
  2. Set Properties:
    • Open the file in Azure Storage Explorer or the Azure Portal.
    • Set the Content-Type to text/css.
    • Set the Content-Encoding to gzip.

This ensures that browsers correctly interpret the files as gzipped and decompress them accordingly.

Creating a Stored Access Policy

Now, let's create a Stored Access Policy to simplify access management.

  1. Log in to the Azure Portal:
    • Navigate to your Storage Account.
  2. Locate the Container:
    • Find the content-hub-external-components container.
  3. Create the Access Policy:
    • In the container's menu, select "Access policy" or "Shared access signature".
    • Click on "Add policy" to create a new Stored Access Policy.
    • Name the policy (e.g., external-components-policy).
    • Set the permissions to "Read".
    • Set the start and expiration dates/times (e.g., 4 years from now).
    • Click "Save" to create the policy.

Generating the Container SAS URL

  1. Generate the SAS URL:
    • Right-click on the container and select "Get Shared Access Signature".
    • In the dialog, select the Stored Access Policy you created.
    • Ensure the "Allowed resource types" is set to "Container".
    • Copy the generated "Blob SAS URL".

The SAS URL will look something like this:


https://<storage-account-name>.blob.core.windows.net/<container-name>?si=<policy-name>&spr=https&sv=<version>&sr=c&sig=<signature>

Accessing Files Using the Container SAS URL

To access a specific file within the container, append the file name to the URL path. For example, to access script.js.gz:


https://<storage-account-name>.blob.core.windows.net/<container-name>/script.js.gz?si=<policy-name>&spr=https&sv=<version>&sr=c&sig=<signature>


This URL allows you to upload, download, or access the file based on the permissions defined in the Stored Access Policy.


Why This Approach Rocks

By using a Stored Access Policy at the container level, you don't need to generate and manage individual SAS URLs for each file. The container-level SAS URL, combined with the file name, provides access to any file within the container. This simplifies access management and reduces the overhead of generating and maintaining SAS URLs for individual files, especially when you have a large number of files.


Wrapping Up

And there you have it! By moving your external component files to Azure and using a Stored Access Policy, you can streamline your deployment process and make it as easy as pie. No more generating new public links for each release—just upload your files, and let the script handle the rest. Bon appétit!


Stay tuned for more tech recipes from the "Restaurant of Mistaken Orders" blog. Until next time, happy coding!

Automate the process
https://www.restaurantofmistakenorders.com/2024/06/sitecore-content-hub-dam-fun-dive-into.html