Site Architecture Articles / Blogs / Perficient https://blogs.perficient.com/category/technical/site-architecture/ Expert Digital Insights Thu, 16 Jan 2025 14:24:49 +0000 en-US hourly 1 https://blogs.perficient.com/files/favicon-194x194-1-150x150.png Site Architecture Articles / Blogs / Perficient https://blogs.perficient.com/category/technical/site-architecture/ 32 32 30508587 Drupal CMS is here, what it means for you and your organization. https://blogs.perficient.com/2025/01/16/drupal-cms-is-here-what-it-means-for-you-and-your-organization/ https://blogs.perficient.com/2025/01/16/drupal-cms-is-here-what-it-means-for-you-and-your-organization/#respond Thu, 16 Jan 2025 14:19:32 +0000 https://blogs.perficient.com/?p=375772

In a previous blog post I discussed various content authoring approaches within Drupal and the importance of selecting the right one for your specific situation. Towards the end I mentioned a new iteration of Drupal(Starshot). It is now here, Startshot, i.e. Drupal CMS was released on Jan 15th. As it becomes part of the Drupal Ecosystem, here are 5 key areas to consider when tackling a new project or build.

 

1. What is Drupal CMS?

Drupal CMS is a tooling built on top of Drupal 11 Core. This takes some of the most commonly used configurations, recipes, modules and more, puts them into an installable package and offers it for a great starting point for small to moderate complexity websites and portals.

 

2. What are the advantages of Drupal CMS?

As mentioned above, Drupal CMS is a pre-bundled installation of Drupal 11 Core, Contributed modules, Recipes and configuration that provides a rapid starting point for marketing teams.

The advantages include quicker time to market, easier configuration of toolings for cookie compliance, content workflows, permissions, multilingual support and more. Drupal CMS as a product will enable marketing teams to build and maintain a web presence with limited technical staff requirements. You may be able to take advantage of an implementation partner like Perficient and have much smaller learning curve for web editors and managers as opposed to a completely custom build on top of Drupal Core.

The ability for a CMS to be spun up with limited customization and overhead, is a big departure from traditional Drupal development which required extensive experience and technical support. This will be a huge time and budget saver for certain situations and organizations.

Another advantage of Drupal CMS is that is built upon the standard Drupal 11 core. This allows a site to evolve, grow and take advantage of the more complex technical underpinnings as needed. If you start with Drupal CMS, you are not handcuffed to it, and have the entire Drupal open source ecosystem available to you as you scale.

 

3. What are the disadvantages of Drupal CMS?

Or course, no situation is a win-win-win, so what are the tradeoffs of Drupal CMS?

The major disadvantages of Drupal CMS would come to light in heavily customized or complex systems. All of the preconfigured toolings that make a simple to moderately complex site easier on Drupal CMS can cause MORE complexity on larger or completely custom builds, as a technical team may find themselves spending unnecessary time undoing the unnecessary aspects of Drupal CMS.

Another (for the meantime)disadvantage of Drupal CMS is that it is built on top of Drupal 11 core, while Drupal 11 is a secure and final release, the community support historically lags. It is worth evaluating support for any contributed modules for Drupal 11 before making the decision on Drupal CMS.

 

4. Drupal 10, Drupal 11, Drupal CMS, which is the right choice?

With all of the advantages and disadvantages to various Drupal Core and CMS versions. It can be a large choice of what direction to go. When making that decision for your organization, you should evaluate 3 major areas. First, look at the scale of your technical team and implementation budget. A smaller team or budget would suggest evaluating Drupal CMS as a solution.

Secondly, evaluate your technical requirements. Are you building a simple website with standard content needs and workflows? Drupal CMS might be perfect. Are you building a complex B2B commerce site with extensive content, workflow and technical customizations? Drupal Core might be the right choice.

Finally, evaluate your technical requirements for any needs that may not be fully supported by Drupal 11 just yet. If you find an area that isn’t supported, it would be time to evaluate the timeline for support, timeline for your project as well as criticality of the functional gaps. This is where a well versed and community connected implementation partner such as Perficient can provide crucial insights to ensure the proper selection of your underlying tooling.

 

5. I am already on Drupal 7/8/9/10/11, do I need to move to Drupal CMS?

In my opinion this is highly dependent of where you currently are. If you are on Drupal 7/8, you are many versions behind, lacking support and any upgrade is essentially a rebuild. In this case, Drupal CMS should be considered just like an new build considering the points above. Drupal 9/10/11, an upgrade to Drupal 10/11 respectively might be your best bet. Drupal CMS can be layered on top of this upgrade if you feel the features fit the direction of your website, but it is important to consider all the above pros and cons when making this decision. Again, a trusted implementation partner such as Perficient can help guide and inform you and your team as you tackle these considerations!

]]>
https://blogs.perficient.com/2025/01/16/drupal-cms-is-here-what-it-means-for-you-and-your-organization/feed/ 0 375772
Don’t try to fit a Layout Builder peg in a Site Studio hole. https://blogs.perficient.com/2024/11/14/dont-try-to-fit-a-layout-builder-peg-in-a-site-studio-hole/ https://blogs.perficient.com/2024/11/14/dont-try-to-fit-a-layout-builder-peg-in-a-site-studio-hole/#respond Thu, 14 Nov 2024 19:39:04 +0000 https://blogs.perficient.com/?p=372075

How to ensure your toolset matches your vision, team and long term goals.

Seems common sense right? Use the right tool for the right purpose. However, in the DXP and Drupal space, we often see folks trying to fit their project to the tool and not the tool to the project.

There are many modules, profiles, and approaches to building Drupal out there, and most all of them have their time and place. The key is knowing when to implement which and why. I am going to take a little time here a dive into one of those key decisions that we find ourselves at Perficient facing frequently and how we work with our clients to ensure the proper approach is selected for their Drupal application.

Site Studio vs Standard Drupal(blocks, views, content, etc..) vs Layout Builder

I would say this is the most common area where we see confusion related to the best tooling and how to pick. To start let’s do a summary of the various options(there are many more approaches available but these are the common ones we encounter), as well as their pros and cons.

First, we have Acquia Site Studio, it is a low-code site management tool built on top of Drupal. And it is SLICK. They provide web user editable templates, components, helpers, and more that allow a well trained Content Admin to have control of almost every aspect of the look and feel of the website. There is drag and drop editors for all templates that would traditionally be TWIG, as well as UI editors for styles, fonts and more. This is the cadillac of low code solutions for Drupal, but that comes with some trade offs in terms of developer customizability and config management strategies. We have also noticed, that not every content team actually utilizes the full scope of Site Studio features, which can lead to additional complexity without any benefit, but when the team is right, Site Studio is a very powerful tool.

The next option we frequently see, is a standard Drupal build utilizing Content Types and Blocks to control page layouts, with WYSIWYG editors for rich content and a standard Drupal theme with SASS, TWIG templates, etc…. This is the one you see most developer familiarity with, as well as the most flexibility to implement custom work as well as clean configuration management. The trade off here, is that most customizations will require a developer to build them out, and content editors are limited to “color between the lines” of what was initially built. We have experienced both content teams that were very satisfied with the defined controls, but also teams that felt handcuffed with the limitations and desired more UI/UX customizations without deployments/developer involvement.

The third and final option we will be discussing here, is the Standard Drupal option described above, with the addition of Layout Builder. Layout Builder is a Drupal Core module that enables users to attach layouts, such as 1 column, 2 column and more to various Drupal Entity types(Content, Users, etc..). These layouts then support the placement of blocks into their various regions to give users drag and drop flexibility over laying out their content. Layout Builder does not support full site templates or custom theme work such as site wide CSS changes. Layout Builder can be a good middle ground for content teams not looking for the full customization and accompanying complexity of Site Studio, but desiring some level of content layout control. Layout builder does come with some permissions and configuration management considerations. It is important to decide what is treated as content and what as configuration, as well as define roles and permissions to ensure proper editors have access to the right level of customizations.

Now that we have covered the options as well as the basic pros and cons of each, how do you know which tool is right for your team and your project? This is where we at Perficient start with a holistic review of your needs, short and long term goals, as well as the technical ability of your internal team. It is important to honestly evaluate this. Just because something has all the bells and whistles, do you have the team and time to utilize them, or is it a sunk cost with limited ROI. On the flip side, if you have a very technically robust team, you don’t want to handcuff them and leave them frustrated with limitations that could impact marketing opportunities that could lead to higher ROI.

Additional considerations that can help guide your choice in toolset would be future goals and initiatives. Is a rebrand coming soon? Is your team going to quickly expand with more technical staff? These might point towards Site Studio as the right choice. Is your top priority consistency and limiting unnecessary customizations? Then standard structured content might be the best approach. Do you want to able to customize your site, but just don’t have the time or budget to undertake Site Studio? Layout Builder might be something you should closely look at.

Perficient starts these considerations at the first discussions with our potential clients, and continue to guide them through the sales and estimation process to ensure the right basic Drupal tooling is selected. This then continues through implementation as we continue to inform stakeholders about the best toolsets beyond the core systems. In future articles we will discuss the advantages and disadvantages of various SSO, DAM, Analytics, Drupal module solutions as well as the new Star Shot Drupal Initiative and how it will impact the planning of your next Drupal build!

]]>
https://blogs.perficient.com/2024/11/14/dont-try-to-fit-a-layout-builder-peg-in-a-site-studio-hole/feed/ 0 372075
Content Hub: Data Model Simplified https://blogs.perficient.com/2024/09/09/content-hub-data-model-simplified/ https://blogs.perficient.com/2024/09/09/content-hub-data-model-simplified/#respond Mon, 09 Sep 2024 16:48:47 +0000 https://blogs.perficient.com/?p=367448

Sitecore Content Hub is a world-class platform for centralizing and managing content across various channels. It helps businesses organize and streamline often chaotic, messy content operations. It does this by providing an architecture or schema for content and its interconnections. A schema defines how different types of assets are structured, organized, related to each other.

What is the basis of that architecture? I struggled with understanding completely when I first began with DAMs. So, hopefully, the following concepts I’ve put into more understandable terms will help make Content Hub’s data model clear for you:

  • Entities: A distinguishable object or concept. A person, a product, a company, a brand. These are the core items in the system.
  • Relations: Connections between entities. How entities are related to each other.
    • Parent-Child relation: two entities where one entity, The Parent, holds a hierarchical position higher than that of its related entity or entities, The Child or Children. The Child is dependent on the Parent.
  • Cardinality: Cardinality is the number instances of an entity that are connected to another entity. It’s the nature and scope of the relation.
    • Cardinality types
      • One-to-one: One item connected with only one other item.
        • Simple example: Mike has a BMX bike, and he owns no other bikes.
        • Real world example: A bicycle has one specific product image used across all marketing materials.
      • One-to-many: One item connected with multiple items.
        • Simple example: Mike has a BMX bike, a mountain bike, and a ten-speed bike.
        • Real world example: A bicycle brand, Cool Cycles, has images, videos, and spec sheets used across all marketing materials.
      • Many-to-many: Multiple items connected to multiple other items.
        • Simple example: Mike, Spike, and Ed have bikes. Mike sometimes rides Spike’s bike, Spike sometimes rides Ed’s bike, and Ed sometimes rides Mike’s bike.
        • Real world example: Cool Cycles has a summer marketing campaign sharing a video from another summer marketing campaign, and both campaigns are sharing images with multiple Q3 campaigns.

All of these interconnected elements create a robust framework for organizing and managing content in a scalable, efficient way, bringing order to content chaos.

 

]]>
https://blogs.perficient.com/2024/09/09/content-hub-data-model-simplified/feed/ 0 367448
Enabling Dynamic Media Feature For AEM Custom Components https://blogs.perficient.com/2024/05/28/enabling-dynamic-media-feature-aem-custom-components/ https://blogs.perficient.com/2024/05/28/enabling-dynamic-media-feature-aem-custom-components/#comments Tue, 28 May 2024 11:50:17 +0000 https://blogs.perficient.com/?p=363473

Dynamic Media is one of the versatile tools provided by Adobe. Previously, it was known as Scene7. It has strong Asset editing and authoring tools capabilities. It is based on a Cache delivery network, which loads the contents to improve page load time and renders the right image renditions correctly resized and optimized. Dynamic Media allows requesting devices to request exactly what type of rendition, version, and exact image size is needed by that device at the moment of request.  

Have you wondered about the benefits of integrating the Dynamic Media feature in custom components?  In this blog, I will demonstrate how to integrate Dynamic Media with custom components and the benefits it provides by doing so.

When we integrate dynamic media with AEM, it enables various Dynamic Media functionalities like image/video profiles, DM metadata, DM workflows, and some set of out-of-the-box Dynamic Media Components. Also, some core components like Image provide Dynamic Media functionality. 

Integrate Dynamic Media With AEM

Integrate Dynamic Media With AEM New Component

If you have not integrated Dynamic Media with AEM, please go through the documentation provided by Adobe on how to Configure the Dynamic Media for AEM.

Loading Dynamic Media Library

First, we need to load dynamic media clientlibs on every page to render Dynamic Media Assets through AEM Components.

Paste the following code into the head section page component i.e. customheaderlibs.html 

<!--/* Dynamic Media Integration */--> 

<sly data-sly-use.clientLib="${'/libs/granite/sightly/templates/clientlib.html'}" 

data-sly-call="${clientLib.all @ categories='cq.dam.components.scene7.dynamicmedia,cq.dam.components.scene7.common.i18n'}"></sly>

Custom Sling Model Implementation 

Then create one custom sling model common utility for reading Dynamic Media assets metadata properties which is required to load any AEM assets through dynamic media functionality. 

Sling model Implementation 

public interface DynamicMedia extends BaseModel { 

String getCurrentPagePath(); 

String getPageLocale(); 

String getAssetName(); 

String getAssetPath(); 

String getDynamicMediaViewerPath(); 

String getDynamicMediaImageServerPath(); 

boolean isWcmModeDisabled(); 

@Slf4j 

@Model( 

adaptables = SlingHttpServletRequest.class, 

adapters = DynamicMedia.class, 

defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL 

) 

public class DynamicMediaImpl implements DynamicMedia { 

private static final String DM_IMAGE_SERVER_PATH = "is/image/";  

private static final String DM_VIEWERS_SERVER_PATH = "s7viewers/"; 

@SlingObject 

private SlingHttpServletRequest request; 

@ScriptVariable 

private Page currentPage; 

@RequestAttribute 

private String imageReference; 

@Getter 

private String assetName; 

@Getter 

private String assetPath; 

@Getter 

private String dynamicMediaViewerPath; 

@Getter 

private String dynamicMediaImageServerPath; 

@PostConstruct 

protected void init() { 

if (StringUtils.isNotEmpty(imageReference)) { 

final Resource assetResource = request.getResourceResolver() 

.getResource(imageReference); 

if (assetResource != null) { 

final Asset asset = assetResource.adaptTo(Asset.class); 

if (asset != null) { 

this.id = getId() + "-" + asset.getID(); 

assetName = asset.getName(); 

assetPath = asset.getMetadataValue(Scene7Constants.PN_S7_FILE); 

final String dynamicMediaServer = asset.getMetadataValue( 

Scene7Constants.PN_S7_DOMAIN); 

dynamicMediaImageServerPath = dynamicMediaServer + DM_IMAGE_SERVER_PATH; 

dynamicMediaViewerPath = dynamicMediaServer + DM_VIEWERS_SERVER_PATH; 

} 

} 

} 

} 

@Override 

public String getCurrentPagePath() { 

return currentPage.getPath(); 

} 

@Override 

public String getPageLocale() { 

return LocaleUtils.generateLocaleFromPath(getCurrentPagePath()); 

} 

@Override 

public boolean isWcmModeDisabled() { 

return (WCMMode.fromRequest(request) == WCMMode.DISABLED); 

} 

}

Once we are done with the Sling model implementation part then create one HTL template inside directory /apps/<Project Driectory>/components/atoms/dynamicmedia/image.html  to provide reusability within the component whenever we want to load any image using dynamic media for a specific component. Paste the following code in the image.html file. 

<sly data-sly-template.dynamicMediaImageTemplate="${ @ imageReference, aspectRatio, altText, suffixId}"> 

<div data-sly-use.dynamicMediaImage="${'com.perficientblogs.core.models.commons.DynamicMediaModel' @ imageReference = imageReference}" 

id="${suffixId || dynamicMediaImage.id}" 

data-current-page="${dynamicMediaImage.currentPagePath}" 

data-page-locale="${dynamicMediaImage.pageLocale}" 

data-asset-path="${dynamicMediaImage.assetPath}" 

data-asset-name="${dynamicMediaImage.assetName}" 

data-asset-type="image" 

data-viewer-path="${dynamicMediaImage.dynamicMediaViewerPath}" 

data-imageserver="${dynamicMediaImage.dynamicMediaImageServerPath}" 

data-wcmdisabled="${dynamicMediaImage.wcmModeDisabled}" 

data-dms7="" 

data-mode="smartcrop" //Note: We can set the image preset mode here 

data-enablehd="always" 

data-aspectratio="${aspectRatio @context='scriptString'}" 

data-title="${altText}" 

data-alt="${altText}" 

class="s7dm-dynamic-media"> 

</div> 

</sly>

Now refer to this HTL template file anywhere in the component HTML where we want to load any authored Image through dynamic media CDN. 

<sly data-sly-use.image=" /apps/<Project Driectory>/components/atoms/dynamicmedia/image.html" 

data-sly-call="${image.dynamicMediaImageTemplate @ imageReference= modeloject.fileReference, aspectRatio= false, altText= 'Hello world Component'}"></sly>

Make sure to pass a value for imageReferenceproperty which is mandatory. We can also pass the values with other objects named aspectRatio, altTextas per the need or extend the functionality as per the requirement. 

Image Url Rendered By Custom Component

See the image above for the final output.  Look at the URL of the image rendered by the custom component.  It is delivered from Dynamic Media provided CDN.  That is the benefit you achieve with this. This way the images will be served much faster to the user based on the region they are in.   

If you have any questions or comments, drop them in the chat below! 

 

]]>
https://blogs.perficient.com/2024/05/28/enabling-dynamic-media-feature-aem-custom-components/feed/ 1 363473
Enhancing Test Coverage with Data Driven Testing in C# https://blogs.perficient.com/2024/05/21/enhancing-test-coverage-with-data-driven-testing-in-c/ https://blogs.perficient.com/2024/05/21/enhancing-test-coverage-with-data-driven-testing-in-c/#respond Tue, 21 May 2024 05:46:02 +0000 https://blogs.perficient.com/?p=363249

A testing technique known as “Data Driven Testing” (DDT) uses test data that is pulled from external data sources like databases, CSV files, Excel files, or other structured data formats. Data-driven testing in C# enables you to run the same set of test scripts with different sets of data, which can greatly improve your test coverage and performance. This blog will walk you through the process of using well-known testing frameworks like NUnit to create data-driven tests in C#.

Why Data Driven Testing?

  • Increased Efficiency: Using a single test method to validate multiple data sets reduces the number of test scripts needed.
  • Enhanced Test Coverage: Different input values and edge cases are tested, ensuring your application handles a variety of scenarios.
  • Simplified Maintenance: Test logic is separated from test data, making it easier to update tests when requirements change.
  • Better Automation: Data-driven tests integrate well with Continuous Integration/Continuous Deployment (CI/CD) pipelines, improving your automation strategy.

Setting Up Your Test Project

Before diving into data-driven tests, you need to set up your test project. If you haven’t already, create a new NUnit test project in Visual Studio or your preferred C# IDE.

  1. Install NUnit and NUnit3TestAdapter: Add the necessary NuGet packages to your project.
  • dotnet add package NUnit.
  • dotnet add package NUnit3TestAdapter.
  1. Create a Test Class: Create a new class to hold your tests. This class should be decorated with the [TestFixture] attribute.Picture1

Creating Data-Driven Tests

NUnit provides several ways to create data-driven tests. We’ll explore three common methods: using the [TestCase] attribute, the [TestCaseSource] attribute, and the [Values] attribute.

Using the [TestCase] Attribute

The [TestCase] attribute is the simplest way to create data-driven tests in NUnit. You can specify multiple sets of input parameters directly in the attribute.

Write Data-Driven Test:

Picture2

In this example, the ‘AddTest’ method will run three times with different sets of parameters.

Picture3

Using the [TestCaseSource] Attribute

The [TestCaseSource] attribute allows you to provide a method or property that returns a collection of test cases. This is useful when you have many test cases or the test data is dynamically generated.

Picture4

Using the [Values] Attribute

The [Values] attribute can be used to pass multiple values to a single parameter. When combined with the [Test] attribute, it creates a test for each combination of parameter values.

Picture5

This will run 9 tests for all possible combinations of a and b.

Conclusion

Using NUnit for data-driven testing in C# is a potent technique that lets you run the same test logic with different inputs, which improves your testing strategy. Data-driven test implementation and management are made simple with NUnit, regardless of whether you use [TestCase], [TestCaseSource], or [Values].

You can make sure your program handles a variety of inputs effectively by utilizing these characteristics, which will result in more dependable and robust software.

Cheers for your testing!

 

 

]]>
https://blogs.perficient.com/2024/05/21/enhancing-test-coverage-with-data-driven-testing-in-c/feed/ 0 363249
Handling Not Allowed Reflection Method in Sitecore https://blogs.perficient.com/2024/05/09/handling-not-allowed-reflection-method-in-sitecore/ https://blogs.perficient.com/2024/05/09/handling-not-allowed-reflection-method-in-sitecore/#respond Thu, 09 May 2024 08:03:47 +0000 https://blogs.perficient.com/?p=357334

Recently, to meet project requirements, we customized and expanded the functionality of the “General Link” feature by incorporating a new “Telephone Link” feature. Everything was working correctly on our local project instance, but we got the below-listed error when the changes were deployed on the higher environment.

Handling Not Allowed Reflection Method in Sitecore

Exception: Sitecore.Exceptions.AccessDeniedException
Message: Calling Fieldtypes.ExtendedGeneralLink.ExtendedGeneralLinkForm.OnModeChange method through reflection is not allowed.
Source: Sitecore.Kernel
   at Sitecore.Reflection.MethodFilter.Filter[T](MethodInfo method)
   at Sitecore.Shell.Framework.Commands.CommandManager.GetMethodCommand(String command)
   at Sitecore.Web.UI.Sheer.ClientPage.Dispatch(String command)
   at Sitecore.Web.UI.Sheer.ClientPage.RaiseEvent()
   at Sitecore.Web.UI.Sheer.ClientPage.OnPreRender(EventArgs e)
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Solutions: Handling Not Allowed Reflection Method in Sitecore

I looked into the problem and discovered the solution provided by Himmat Singh Dulawat in this article. Since it was my first time implementing these required patch solutions, I wasn’t familiar with the proper patch file hierarchy or the pattern that needed to be added correctly. Below is the necessary configuration structure for adding the patch file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:security="http://www.sitecore.net/xmlconfig/security/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
     <reflection>
        <allowedMethods>
           <!--For example: <descriptor type="SampleNameSpace.MyClass" methodName="MyMethod" assemblyName="MyAssembly"/> -->
           <!--Allowed Methods-->
           <descriptor type="Fieldtypes.ExtendedGeneralLink.ExtendedGeneralLinkForm" hint="ExtendedGeneralLinkForm.OnModeChange" methodName="OnModeChange" assemblyName="Fieldtypes"/>
        </allowedMethods>
        <allowedPatterns>
            <!--Default-->
            <pattern value="^Sitecore\..*,Sitecore\..*$"/>
            <!--Add additional allowed method patterns-->
            <pattern value="^Fieldtypes\..*,Fieldtypes\..*$"/>
        </allowedPatterns>
     </reflection>
  </sitecore>
</configuration>

In our situation, we encountered an issue where multiple “allowedMethods” were present, and we added all the methods in the patch file. However, after deployment and verifying it using the showconfig file, only the last method was added within the allowedMethods.

Upon reviewing the patch files, we realized that since all the “allowedMethods” belonged to the same class and we were not using the “hint” attribute, it took only the last method. Once we added the “hint” attribute, our issue was resolved.

Click the “GitHub – Reflection Filtering Patch” link to access the detailed configuration needed to resolve the reflection issue.

The GitHub config file changes were initially implemented for the “Extending General Link for Experience Editor” enhancements. Everything was functioning correctly, along with additional patch file configurations for reflections. However, after thorough testing, we decided to optimize our code and reduce the number of allowedMethods.

Therefore, we introduced the “Extending General Link for Experience Editor Alternate Approach.” This new approach reduced the allowedMethods configuration from 7 to 1. The optimized allowedMethods code according to our alternate approach is displayed below.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:security="http://www.sitecore.net/xmlconfig/security/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <reflection>
      <allowedMethods>
         <descriptor type="Fieldtypes.ExtendedGeneralLink.ExtendedGeneralLinkForm" hint="ExtendedGeneralLinkForm.OnModeChange" methodName="OnModeChange" assemblyName="Fieldtypes"/>
      </allowedMethods>
      <allowedPatterns>
         <pattern value="^Fieldtypes\..*,Fieldtypes\..*$"/>
      </allowedPatterns>
    </reflection>
  </sitecore>
</configuration>

Conclusion

We addressed the “Reflection Method” error by configuring the patch file hierarchy and implementing the proper method pattern. This ensured smooth functionality in our project. Additionally, we optimized our code by reducing the number of allowed methods following an alternate approach outlined in the “Extending General Link for Experience Editor Alternate Approach” enhancements. This streamlined our codebase, enhancing efficiency and reliability.

Hope this helps. Happy learning!

]]>
https://blogs.perficient.com/2024/05/09/handling-not-allowed-reflection-method-in-sitecore/feed/ 0 357334
Which Components Are Available Out of the Box with Sitecore XP Using SXA? A Quick Reference Guide https://blogs.perficient.com/2024/03/26/which-components-are-available-out-of-the-box-with-sitecore-xp-using-sxa-a-quick-reference-guide/ https://blogs.perficient.com/2024/03/26/which-components-are-available-out-of-the-box-with-sitecore-xp-using-sxa-a-quick-reference-guide/#respond Tue, 26 Mar 2024 15:09:43 +0000 https://blogs.perficient.com/?p=360364

When planning a new website, a web development team must identify the essential components required for completion. These pieces are often called components. Assuming the site is being built using a Content Management System (CMS), most, if not all of these platforms will have their own set of “out of the box” components. Out of the box means that the leg work has already been done in terms of building these components out and should only need styling applied to make them really pop.

Sitecore is no exception to a DXP having its own set of out of the box components, and in this post we will go over what is available for a development team building a site on Sitecore XP. This post can serve as a quick reference. In later posts, we will take a deeper dive to see how each component can be used in building out an exceptional digital experience across your organization’s website.

First off, within Sitecore, there are a variety of composites – a fancy way of saying “categories of components”. This is how the components will be organized for a content author when assembling a webpage in Experience Editor. Now, let’s break down each composite and its associated components available out of the box within Sitecore XP using the Sitecore Experience Accelerator (SXA).

Composites

Accordion
Carousel
Flip
Tabs
Snippet

 

Context

Language Selector
Site Selector
Engagement
Facebook Comments

 

Events

Event Calendar
Event List

 

Forms

WFFM Wrapper
Sitecore Forms Wrapper
MVC Form

 

Maps

Map

 

Media

File List
Flash
Gallery
Image
Image (Reusable)
Media Link
Playlist
Video

 

Navigation

Archive
Breadcrumb
Link
Link List
Navigation

 

Page Content

Field Editor
Page Content
Page List
Pagination
Plain HTML
Plain HTML (Reusable)
Promo
Rich Text
Rich Text (Reusable)
Title

 

Page Structure

Container
Divider
Edit Mode Panel
IFrame
Splitter (Columns)
Toggle

 

Search

Filter (Checklist)
Filter (Date)
Filter (Dropdown)
Filter (Managed Range)
Filter (Radius)
Filter (Range Slider)
Filter (Slider)
Load More
Location Finder
Page Selector
Page Size
Results Count
Results Variant Selector
Search Box
Search Results
Sort Results

 

Security

Login
Logout
Social Login Wrapper

 

Social

AddThis
Feed
Social Media Share
Twitter
Disqus

 

Taxonomy

Tag Cloud
Tag List

 

Clearly, Sitecore has, if nothing else, put you on a fast track to shortening project timelines while setting the future architecture of your site up for success, using its out of the box components. Looking for a Sitecore partner to help take your site to the next level? The experts at Perficient our here to help! Reach out today to find out how we can work together to bring your organization’s digital experience to the next level.

Source: https://doc.sitecore.com/xp/en/users/sxa/17/sitecore-experience-accelerator/the-sxa-renderings-and-rendering-variants.html

]]>
https://blogs.perficient.com/2024/03/26/which-components-are-available-out-of-the-box-with-sitecore-xp-using-sxa-a-quick-reference-guide/feed/ 0 360364
Sling Mappings++ Large Lists and Mapping Arrays https://blogs.perficient.com/2024/03/22/unleash-the-power-of-sling-mappings-fallback-arrays/ https://blogs.perficient.com/2024/03/22/unleash-the-power-of-sling-mappings-fallback-arrays/#comments Fri, 22 Mar 2024 16:16:08 +0000 https://blogs.perficient.com/?p=360041

As all AEM Developers know, AEM, and more-so the underlying JCR, has limitations on how many children a single parent can have before we start to see performance issues.  First in the UI, and then more critically in the ability to look-up and manage content nodes themselves.  When designing for a net-new AEM website, this can be planned around, however, many times when dealing with a migration, there may be requirements to both keep existing links in-tact, which may put us in a situation where a large flat list, at least as exposed to the end-user, is unavoidable.

In this post, I will not go down the rabbit hole of whether 500, 1000, or 10000 children would start to have performance issues (although I do certainly have opinions here), and instead will focus on ways to allow for a single parent, to appear to have many more than the maximum number of children.

Enter Sling Mappings

Now, Sling mappings are not new for most, and commonly used for things like stripping the initial prefix (/content/<project>) away from outgoing URLs, but these mappings have additional untapped power which documentation, in my opinion, does not clearly emphasize.  Before we jump in, lets talk about a few key features of sling mappings as a whole.

Sling mappings are configured based on regular expressions, and often inherited by the node names themselves, within /etc/map.  Within each node, there are optional properties we can add to define how mappings should behave.  For example, if we are wanting to introduce a higher complexity regular expression, we cannot rely on the node name alone (characters required for regex mappings are restricted from being used as a node name).  This means that when we need to define a mapping which does NOT align with the name of the node, we can insert the following property (single value only):

sling:match <Regular Expression or Reverse Regular Expression>
sling:match content/wknd/us/en/magazine/(.*)

Now, the above is a relatively straight-forward example, but we’re here to learn about mappings, not regular expressions.  Do note, I am using a capture group here – multiple capture groups are certainly also supported, but for ease of this post, am keeping it quite simple.

Mappingonrootnode

The other item to note on the above is that I have added this node as a root node in the /etc/map/localhost tree.  As such, the mapping begins from the root element.  If we were to structure the /etc/map node differently, the start-point of that regular expression would change as well, for example:

Mappingonnonrootlevel

In the above scenario, we’d structure the sling:match accordingly, as the content and wknd nodes would have already been matched against:

sling:match us/en/magazine/(.*)

Well, that is half of the issue, is being able to capture the incoming request.  Next is to actually map it to a different internal resource.  This is where the “magic” comes in – on the same node, add an additional property, sling:internalRedirect, as follows:

sling:internalRedirect <path(s) to look for the matched content>
sling:internalRedirect /content/wknd/us/en/magazine/$1

In the above, we’re really just finding content in the same location it was requested.  The $1 in the internalRedirect is referencing the (.*) of the sling:match property, and saying that whatever was matched there, should first look at the location requested to find the resource, technically speaking, we have not really mapped anything at this point.   Now, what if the magazine section above is a long-standing blog, which has all urls published under the same /magazine root.  If organized 1:1 with the JCR structure, this would quickly cause reason for concern!  This is where the often overlooked ARRAY support of the internalRedirect comes to save the day.  From here, we can supply alternative locations to look for the same page.  For example, if we were to archive posts on a yearly basis, as in 2023 posts would live in the JCR structure /content/wknd/us/en/magazine/2023/<post>, while being publicly available still under /content/wknd/us/en/magazine/<post>, we could configure that using the “internalRedirect” array, as follows:

 

sling:internalRedirect /content/wknd/us/en/magazine/$1, /content/wknd/us/en/magazine/2023/$1

 

Now, when a request matches, it will first search under the magazine root folder, and if it does not find a resource there, will look to the 2023 folder, and so-on until all items of the Array have been searched against.  It does search from the top, down, so this means that order is important, especially if same-name nodes are expected.  If the entire list is exhausted and there is no resource found, then the normal 404 behavior is observed.

Now, lets assume we’ve got the following content (note the 2023 and 2024 folders added, with children):

Contentexample

With the forward mapping applied, we should be able to access the “san-diego-surf-2023” and “san-diego-surf-2024” under the /magazine folder directly.  Lets test it out!

Correctlymappedurl

Awesome.  We’re accessing the content without using the “2023” folder in the URL!

 

Great!  Well this solves the problem of accessing the content, however, if we look at a page which links to this content, we still are seeing an issue….

Incorrectlymappedlink

Looks like we still have one other piece of the puzzle to solve for.  One other important thing to know about regular expressions (with capture groups) is that when including in a sling mapping, they will only work in one direction.  Since we have configured it to capture on the request side (match) it will only handle the logic of handling the request.  In order to create a rewrite of outgoing URLs, we will need to also handle the reverse mapping.  For this, I use the suffix “-reverse” with the same node name as initial mapping for consistency.

 

So, next step is to copy the node we just created, and paste it as a sibling (under same parent).  We’ll then reverse the regular expression logic to have capture groups in the “sling:internalRedirect” property, and the references in the sling mapping property, as follows:

 

sling:match /content/wknd/us/en/magazine/$1
sling:internalRedirect /content/wknd/us/en/magazine/(.*),/content/wknd/us/en/magazine/2023/(.*)

 

Reversemappingonrootnode

 

This behaves in much the same way as the other mapping node, but because we have swapped the matching logic for the regular expression, it will now be applied in the url rewriting or output sling mapping as well.

 

Now, lets take a look back at our links to this content, and….

Correctlymappedlink

We’re golden!  Content is hosted under multiple JCR Nodes while being exposed under a single parent to the end-user.

 

I would like to add a disclaimer here: while this method is certainly a suitable work-around, a much more desirable implementation would have the JCR structure more closely matching the expected sitemap.

 

Hope this quick demonstration has been helpful!

 

 

Reference:

]]>
https://blogs.perficient.com/2024/03/22/unleash-the-power-of-sling-mappings-fallback-arrays/feed/ 3 360041
Perficient: Gold Sponsor at Vercel’s Next.js Conference 2023 – Join Us In-Person or Virtually! https://blogs.perficient.com/2023/10/23/perficient-gold-sponsor-at-vercels-next-js-conference-2023-join-us-in-person-or-virtually/ https://blogs.perficient.com/2023/10/23/perficient-gold-sponsor-at-vercels-next-js-conference-2023-join-us-in-person-or-virtually/#respond Mon, 23 Oct 2023 12:18:59 +0000 https://blogs.perficient.com/?p=347590

At Perficient, we’re thrilled to announce that we are a Gold Sponsor of this year’s Next.js Conference, hosted by Vercel. This much-anticipated event will take place on October 26th at the iconic SF Jazz in San Francisco, and just like last year, it will feature a vibrant virtual component for attendees to stream for free. In 2022, more than 50,000 enthusiasts joined us virtually, and this year promises to be even bigger and better.

We’re looking forward to the keynote from Guillermo Rauch and Lee Robinson and what announcements, new offerings and enhancements to Next.js there will be that we can take advantage of in our projects. We’re also looking forward to hearing where Vercel is going with AI from Jared Palmer. Vercel’s, new prompt driven code generation tool v0 is in alpha but already impressive with what it can generate and iterate on based on what you tell it what to do.

Besides that, there are going to be plenty of sessions that promise to be enlightening. Looking at the agenda, there will be plenty that address building a composable architecture, optimizing Next.js performance and making migrations to the platform more efficient. With speakers from Google, Netflix and Disney, there is a lot to look forward to.

Our Partnership with Vercel:

Perficient has cultivated a strong partnership with Vercel, and we’ve worked on numerous projects leveraging their cutting-edge platform. This collaboration has enabled us to deliver exceptional results for our clients, particularly in the realm of modern web development. We’re excited to share our insights and experiences with you at the Next.js Conference.

One of our core strengths is implementing Next.js front-end websites, and we’ve seamlessly integrated them with leading enterprise headless Content Management Systems (CMSs). Our expertise extends to platforms like Adobe, Sitecore, Optimizely, Acquia, and Contentful. We’re passionate about pushing the boundaries of what’s possible in web development and can’t wait to discuss our success stories with you.

Join Us in San Francisco:

For those attending the conference in person at SF Jazz in San Francisco, be sure to visit our booth. We’d love to meet you, discuss your project ideas, and explore potential collaborations. Our team will be on hand to answer your questions and share the latest trends in web development.

Virtual Swag from Perficient:

For all conference attendees, whether you’re joining in person or virtually, we have something special for you. We’re excited to offer a free guide titled “The Modern Ethos of Customer Experience.” This downloadable guide explores 10 undeniable truths about customer experience that will spark meaningful conversations, provide intellectual value, and inspire impactful actions within your organization.

Stay tuned for more information on how to access this exclusive guide. It’s our way of showing appreciation for your participation in the Next.js Conference.

We’re counting down the days until the conference, and we hope you are too! Join us at SF Jazz in San Francisco or tune in virtually to connect with Perficient, learn from our experts, and discover the future of web development.

See you at the Next.js Conference 2023!

]]>
https://blogs.perficient.com/2023/10/23/perficient-gold-sponsor-at-vercels-next-js-conference-2023-join-us-in-person-or-virtually/feed/ 0 347590
Why Do You Need to Know Backend for Frontend (BFF) Pattern? https://blogs.perficient.com/2023/10/17/why-do-you-need-to-know-backend-for-frontend-bff-pattern/ https://blogs.perficient.com/2023/10/17/why-do-you-need-to-know-backend-for-frontend-bff-pattern/#comments Tue, 17 Oct 2023 14:35:28 +0000 https://blogs.perficient.com/?p=346993

Our typical problem arises when we wish to incorporate an API into our mobile app. Consider the situation in which you need to create a mobile app for an existing system. The system was one monolithic solution that exposed an API that exclusively served the web client.

Bff 1

The client’s proposal is not restricted to new mobile apps, but he also considers voice assistants and third-party services that will utilize our API. Hence, one API must handle all these types of clients, and we must take care of their requirements and maintenance.
Bff2

The Backend for Frontend pattern can be of helping hand in this situation.

Backend for Frontend (BFF) Design Pattern:

Now, Consider the user-facing application to have two components: a client-side application located outside your perimeter and a server-side component (BFF) located within your perimeter. BFF is an API Gateway variation but adds an extra layer between microservices and each client type independently. It replaces a single point of entrance with many gateways. As a result, you may have a customized API that caters to each client’s demands (mobile, Web, desktop, voice assistant, etc.) and eliminates a lot of the bloat created by putting everything in one place. The graphic below depicts how it works.

Bff 3

Why BFF?

The advantage of this architecture is that it allows you to optimize each backend for the unique requirements of different client types, which can lead to better performance and a more tailored user experience. It also improves maintainability and code separation. However, it does introduce some complexity in managing multiple backend services.

The BFF can benefit from masking unneeded or sensitive data before transmitting it to the frontend application interface, allowing keys and tokens for third-party services to be saved and used directly from the BFF.

We can maintain and upgrade APIs more quickly and even give API versioning to specific frontends. This is a significant bonus for mobile apps because many users do not update the app immediately.

Allows for the transmission of formatted data to the front end, allowing for the reduction of logic.

Decoupling the backend and frontend allows us a faster time to market because frontend teams can have separate backend teams serving their unique requirements, and the release of new features in one frontend has no effect on the other.

Furthermore, provide us with opportunities for performance enhancements and mobile optimization.

Remember that BFF architecture is only one approach, and whether it is appropriate for your project is up to your individual requirements and restrictions.

Conclusion

A design pattern called Backend for Frontend was developed with the user and their experience in mind, as well as the developer and their needs. It answers the ever-growing adoption of applications to meet, interact, and serve customers. It ensures consistency while addressing their wide range of changing conditions.

]]>
https://blogs.perficient.com/2023/10/17/why-do-you-need-to-know-backend-for-frontend-bff-pattern/feed/ 1 346993
Making Sense of Sitecore’s Headless Options https://blogs.perficient.com/2023/09/11/making-sense-of-sitecores-headless-options/ https://blogs.perficient.com/2023/09/11/making-sense-of-sitecores-headless-options/#respond Mon, 11 Sep 2023 12:27:43 +0000 https://blogs.perficient.com/?p=344383

If you read my last article, the big deal with headless, you know that the big deal is performance. The architecture you get leveraging a headless architecture with Next.js front end is fundamentally superior to MVC. When you are ready to make the move to headless, you may be surprised that there isn’t just one way to do it.

Sitecore offers multiple options for implementing headless architecture, each catering to different needs and scenarios. Organizations can choose the option that best aligns with their existing Sitecore setup, licensing preferences, performance requirements, and the desired feature set, whether it’s a more traditional XM or XP topology with Sitecore Headless Services, the performance-driven Experience Edge for XM, or the fully SaaS XM Cloud offering with advanced content management & personalization capabilities.

 

Sitecore Headless Options

 

Option 1: Sitecore Headless Services for XM and XP Topologies

Sitecore Headless Services is compatible with both XM (Experience Management) and XP (Experience Platform) topologies, offering flexibility to organizations using either edition. It adds GraphQL and Layout APIs to the CD (Content Delivery) servers, reducing the load when compared to full rendering pipelines. This means that the CD servers only need to server APIs for front-end applications reducing their overall load.

Keep in mind that hosting your front-end application requires a new piece of infrastructure: the Rendering Host. This component hosts the front-end applications that consume content through the headless services. We typically recommend a serverless platform like Vercel or Netlify to make it easier to deploy and scale this application. These platforms have the distribution needed to drive better performance than you trying to manage it yourself.

Although this topology technically supports XP, in order to leverage features like analytics and personalization, your pages will need to be server-side rendered, which isn’t as efficient as server-side generation and incremental static generation. Although you can implement components using these strategies, it can quickly lead to confusion if some components support and others do not support personalization.  We highly recommend looking into SaaS optimization platforms like CDP and Personalize for this reason.

Usually, Sitecore Headless Services can be implemented using the current licensing model, providing a seamless transition for existing Sitecore users, however, we have seen clients on perpetual licenses need to negotiate with Sitecore to add this capability to their license.

 

Option 2: XM with Experience Edge

Although performance will be better than a traditional MVC implementation, there are a few areas in the architecture of option 1 that could be improved. The dependence on CD servers to serve the APIs to the front-end service forces you to manage and scale those servers to support the load. The API’s themselves run in a similar pipeline and are managed by similar caching strategies to traditional MVC solutions.

Alternatively, you can add Sitecore’s Experience Edge to your architecture. Experience Edge introduces a new publishing target that significantly enhances performance by storing content in Sitecore’s Distributed Edge Cache, reducing the need for traditional CD servers and Web databases.

It is important to note that this “publish time” caching of the content and relationship between pages and their data sources also helps drive better performance, but also requires content authors to understand how this works.  Instead of updating a child data source and publishing that, they need to go republish the page it belongs to to properly update the cached version of the page.

While it streamlines the architecture by eliminating the requirement for CD servers and Web databases, organizations can choose to implement both, if custom APIs or advanced search functionalities are needed.  Keep in mind doing this may lead to inconsistency issues if the same content is not published to both the web database and Experience Edge.

Accelerating Content Delivery

Experience Edge accelerates content delivery but does not support Sitecore Analytics or Marketing features. This makes sense if you think about it, as your front-end application is getting cached versions of the content at the time of publishing from an edge service. There is no use context or rules to execute in this context. This is another reason why we recommend looking into SaaS optimization platforms like CDP and Personalize.

Implementing Experience Edge requires additional licensing beyond the standard Sitecore licensing, reflecting the added performance enhancements it offers.

 

Option 3: XM Cloud

XM Cloud is a fully SaaS (Software as a Service) solution that only supports headless architectures. It includes Experience Edge as part of the package, offering the same benefits mentioned in Option 2. Additionally, it provides a host of new features not available on the platform DXP offerings. With XM Cloud, your CM (Content Management) server is hosted and managed by Sitecore. You publish to Experience Edge and deploy front-end applications that consume those API’s.

There are no CD servers in this architecture or an option to add them. There are also no “Web DB” or SOLR indexes as well. The implications of this fact will need to be reflected in your solution architecture. API’s will need to be built in either the front-end application (service managed by Next.js) or a middle-tier app services.

If you have search requirements, you need to consider a composable search solution like Sitecore Search or Coveo. Although GraphQL can support basic search and list scenarios, for anything more advanced you’ll need something more capable. Read my article on making sense of search options in Sitecore for more details.

That being said, there are plenty of reasons that make XM cloud the best platform for you. You can get the best performance of the three options and never have to upgrade the platform. Sitecore has traditionally released a new major version every year and most clients go through an upgrade cycle every 3 years since the upgrade process can be heavy involving standing up new infrastructure, upgrading the solution, and redeploying it. See Martin Miles Upgrade guide for more details.

Features, Enhancements, and Moving into the Future of Sitecore

Instead, you’ll get new features automatically. These features are released multiple times a month. Look at the XM Cloud changelog to see what kind of things are being done. There have been several impressive enhancements over the last few months including adding support for SSO and new features like Sitecore Components currently in preview.

It’s important to note that a lot of these enhancements are being made to related XM Cloud SaaS Applications, like Sitecore Deploy and Sitecore Pages do not impact the customizations you’ve made to your CM environment at all. When changes are made to CM, they are done to the root Container Images and can be tested and rolled out only when you want to.

Speaking of Sitecore Pages, it is clear that XM cloud is where Sitecore sees its future. Its next-generation authoring environment: Sitecore Sites and Pages provides a better and faster content authoring experience that Experience editor (which is still supported in XM Cloud).

XM Cloud is where Sitecore is innovating. Sitecore Components, their new Front end as a service component builder is currently in preview and will allow marketers to quickly create and publish new components without the need for a developer.

XM Cloud even comes with a lightweight version of Sitecore Personalize, allowing for page-level personalization and providing basic analytics capabilities. Megan Jensen broke down the personalization capabilities of XM Cloud in a blog post earlier this year.

Choosing Your Own Adventure

Sitecore gives us a few different options for implementing headless solutions. XM Cloud is probably the most compelling one, but there may be reasons for looking at options 1 and 2. If you do go that route, I advise you to consider the architecture implications that I mentioned for XM cloud and solve for them to avoid them being a barrier for adoption down the road.

Given the SaaS nature of XM cloud and the number of enhancements being added every month and features already known to be on its roadmap, it’s a matter of time before that offering is compelling enough for every solution to consider moving to.

Ready to begin your Headless journey? We’d love to help. Reach out to me on LinkedIn, Twitter or fill out our contact form.

]]>
https://blogs.perficient.com/2023/09/11/making-sense-of-sitecores-headless-options/feed/ 0 344383
My Very First JavaScript Code https://blogs.perficient.com/2023/07/27/my-very-first-javascript-code/ https://blogs.perficient.com/2023/07/27/my-very-first-javascript-code/#respond Thu, 27 Jul 2023 10:32:52 +0000 https://blogs.perficient.com/?p=339239

“I can Talk JavaScript, I can walk JavaScript, I can Laugh JavaScript because JavaScript is a very Funny Language.”

It’s really a fun writing JavaScript code in the beginning like you can show a pop-up alert, can set a condition to show results and you can also do mathematical calculations in the console.
Just press Ctrl+Shift+J and you are there. This shortcut will open the browser console in Windows and Linux where you can write your first JavaScript code as I do. You can also use Option + ⌘ + J on macOS.
Let’s start with our first JavaScript code – An alert pop-up – that may be funny and blowing someone’s mind if you write something like this:

 

alert('Click OK to uninstall the browser')

Javascript Pop Up Alert

 

Now you are thinking that how this can blow someone’s mind if I have to write this in console in front of them.

You can learn in my further blogs that how you can show an alert like this in your webpage by add a simple code in your page source.

 

<button onclick="myFunction()">Try it</button>

<script>
var myVar;

function myFunction() {
    myVar = setTimeout(alertFunc, 3000);
}

function alertFunc() {
  alert("Hello!");
}
</script>

 

Another one is how we can add conditions to show some results. But before this, let us learn about operators that will help you to define the condition i.e. ( = , == , === ).

What is =, == & === in JavaScript?

  1. Equal to “ = ” is an assignment operator which sets the variable on the left of “ = ” to the value of the expression on the right.
    • Example: firstName = “Sanju”;
  2. Double Equal “ == ” is known as the equality operator. It is used to compare two values for equality, without considering their data types. When you use == to compare two values, JavaScript performs type coercion if necessary to make the values comparable.
  3. Triple Equal “ === ” is known as the strict equality operator. It is used to compare two values for both equality of value and equality of type. When you use === to compare two values, JavaScript checks if the values are identical in both type and value.

Here is another basic JavaScript code that will bring you a step ahead in your training.

 

let js = 'Funny'

 

If till now you found the blog funny then you can write js = “funny” else you can use funny only, no other option from my side.

Just kidding!
Assign whatever value you want, it’s on you. Here I assign ‘js’ as ‘funny’ using assignment operator “ = ” and set a string ‘funny’. It will show a result as undefined as we haven’t written here what we want from this value.

Then we will write:

 

if (js === 'Funny') alert(JavaScript is Fun')

 

Here, first we define the js as being funny and here in the next line we said that if js strictly equal (===) to funny then JavaScript should show us an alert window with the text ‘JavaScript is FuN!’. Here we are using strict equality operator so that it will strictly compare both the values as this is very helpful when we are using various variables in our JavaScript File.

Javascript Is Fun

]]>
https://blogs.perficient.com/2023/07/27/my-very-first-javascript-code/feed/ 0 339239