Category Archives: Uncategorized

Chrome and Public Sites Caching

Sometimes, you find little quirks that Google doesn’t seem to find the answer. Today was one of those quirks. I’ve been building a public site that is accessed via a link emailed to a customer. The link is only good for one use – once it is visited, the access code becomes invalid. In my testing, everything worked well – I’d visit the page, refresh the browser and an error page would be displayed.  Perfect. The problem came in when testing using the email links. In Chrome, I found that if I followed the link from my email, the link would work multiple times. I pulled up Chrome Developer Tools and found that the entire page was being loaded from cache – Salesforce was never even being hit! If I refreshed the browser or put my cursor in the address bar, then the request was going to Salesforce and I was getting expected results.

The solution to this is to use the cache attribute of the page tag. After adding cache=”true” to my page, Salesforce would be hit every time. Things like images and js files are still loaded from cache if possible, but setting cache to true forces any Apex controllers to run and check to make sure all is well.

In conclusion, in my situation I needed to turn off caching, but in others, it may make sense to have a faster public site to turn on caching. It will also reduce traffic on the site and avoid limits if your site is popular.

Multi-Language Email Templates Using Visualforce Components

In the previous post, I showed how to create basic email templates using custom labels. This works well for simple templates that don’t need a lot of merge fields. In this post, I’ll show an alternative using Visualforce components.

First a high level overview. Rather than create a single email template, we will create one template for each language. We will then create a Visualforce component that retrieves the appropriate template, performs the merge and then outputs the content into another email template. Kind of confusing, but bear with me.

  1. Create Email Templates

Create an HTML email template for each language you want to use.

English Template
German Template

2. Create a Custom Label

Create a custom label that will store the Ids of the email templates created in step 1. You’ll just add a “translation” for each label that will contain the Id for the appropriate language. I’m not a fan of hard coding Ids and you could get fancier by using the API name of the email templates instead, but for simplicity sake, I’m just using Id here.

3. Create Apex Controller 

Now we need an Apex Controller that can take an arbitrary email template Id, merge it with a record Id, and output the final result. The key here is we are going to use Messaging.renderStoredEmailTemplate that takes an email template Id, a what Id and  a who Id and creates a merged email. See the gist below for the code.

4. Create a Visualforce Component

This component will return the HTML or text body of the merge email template. See gist below for the code.

5. Create Final Email Template

For the final email template, you need to create a Visualforce template that uses the component created above.

  • For the subject, you have to use the Substitute function I used in the previous post because subject can’t use custom controllers.
  • Set the language so the custom labels pull in the correct email template Id.
  • Reference the component for both the html and plain text version.

Wrapping Up

In this post, I’ve introduced another way to dynamically translate your email templates. You can also use this technique to reduce the number of workflows and email alerts you create for other types of notifications. I’d love to hear other ideas you have on how to use the dynamic email component.

Multi-Language Email Templates Using Custom Labels

As you start expanding your Salesforce org, you may find you need to send notifications in multiple languages. In this post, I’ll show how you can do it using Custom Labels. The documentation alludes to using labels, but doesn’t really explain how to do it.

Before we get started, you’ll need to enable Translation Workbench and enable the languages you want to use.

In this example, I’m going to use a field on the record to determine the notification language. Create a picklist field on the object you want to send the notifications from.  Use the new feature available in Spring 17 so you can have a different API name than label as in the screenshot below.

Next, we need to setup some custom labels. In this example, I’m just going to create two custom labels: one for the subject and one for the body. Obviously, you might need many custom labels to support your real email templates. In the subject, you’ll notice I put in a placeholder ({0}). I’m going to use this in the email template to substitute in the record name.

Now that we have the custom field on the object and the custom labels setup, we can create an email template. We have to use a Visualforce email template to get it to work correctly.

Test it with a record with the language field set and you’ll see the template translated.

Implementing this in the real world gets complicated quickly when you want to merge in fields from the source record, combined with different language syntaxes. I attempted to show one technique using a placeholder, but it isn’t easy to use. In my next post, I’ll show another way to do it.

 

Use Field Aliasing for ConvertCurrency

This post is more of a cautionary tale so you won’t be a bonehead like me. I recently wrote some code that queried OpportunityLineItem and used the ConvertCurrency function to get the TotalPrice in the user’s currency. The problem was that later in the code, I did an update to that same record. Since I had converted the currency using the formula, the update replaced the value with the converted value, but left the record currency in the foreign value.

My solution was to use a new feature in Spring 16 that lets you alias ConvertCurrency fields. With the field aliased, updates no longer change the monetary value, and problem solved!

OpportunityLineItem oli = [Select Id, convertcurrency(TotalPrice) usdprice from OpportunityLineItem where Id = '00k4B000003ESxW'];
// Use get to access the value
System.debug(oli.get('usdprice'));
// Safely update without overwriting the value
update oli;

Avoiding Hard Coded URLs

Hopefully you know that hard coding links in Salesforce is a no-no. You might one day be migrated from one instance to another (NA1 to NA9999, or whatever they are up to these days). You also want to make sure that your links work in all your sandboxes. There is nothing worse than clicking on a link in a sandbox and all of a sudden you are in production!

First of all, I recommend that you implement My Domain. This means that you won’t have to worry about moving from one instance to another. Plus you need it on to use Lightning Components. You want those, right?

For the most part within Salesforce, you can just avoid the beginning part of the URL and use relative URLs. So, a URL button that takes you to a Visualforce page can just have ‘/apex/MyPage’.

The first “gotcha” is with managed packages. If you want to link to pages in a managed package, then you can still use a relative URL. Just use the format of ‘/apex/NAMESPACE__ManagedPage’.

Another good trick is to use the URLFOR function within Visualforce. This future proofs your pages so that if Salesforce ever changes the URL scheme (hello, Lightning), everything will still work. For example, to get the link to edit an account, I can use the following syntax.

{!URLFOR($Action.Account.Edit, account.id)}

Email templates are another tricky part of links. Since the email is being sent out, you can’t use relative URLs. You need to link into your instance. For the object that is triggering the email, you can use the merge field called Detail Link. This looks like {!Opportunity.Link}.

But what if you want to provide a link in your email to a related record? For example, an email gets sent from an opportunity, but you want a link to the account? First, let’s create a formula field on the object that will trigger the email and call it Base URL and make it a text formula field with the following formula:

LEFT($Api.Partner_Server_URL_360, FIND( '/services', $Api.Partner_Server_URL_360))

You can now use this formula field in your email templates to link to other records or Visualforce pages. So, from an opportunity email, the merge field would be: {!Opportunity.Base_URL__c}{!Opportunity.AccountId}.

By implementing these changes, you can be assured your links will always go to the correct instance.

Salesforce Productivity With Chrome Extensions

I’ve seen several posts recently about Chrome extensions that help with your productivity in Salesforce. Here are a few I use every day.

Boostr for Salesforce

This new extension has several features. My favorite is that it removes the placeholder text from the search box in setup. How many times have you clicked into that box before the page finishes loading?

Salesforce Admin Check All

This handy little extension adds a checkbox at the top of admin page lists so you can quickly grant access to a big list of fields.

Salesforce API Field Names

I have mixed results with this extension. When it works, it replaces the labels on a page with the API names. It doesn’t work on feed based layouts and sometimes the order gets off. I haven’t quite figured out the reason why.

Salesforce Colored Favicons

If you ever have multiple orgs open at once, this extension changes your favicon different colors based on the instance you are on. This lets you easily know if you are in production or a sandbox.

Salesforce Quick Login As

I’ve saved my favorite for last. You can login as another user from any page in Salesforce and it takes you directly to that page as the user. No more going to setup, finding the user, logging in and then navigating to the page you want to look at.

 

Deleting a Single Item From the Recycle Bin

Sometimes you just want to remove a single item or a subset of items from the recycle bin without emptying the entire thing. I found this long-standing idea on IdeaExchange, and then realized I could do it in Apex.

First step is to find the Id of the record you want deleted from the recycle bin. I use workbench to create my SOQL query and query deleted items. Be sure to select the option to include deleted and archived records. Here’s a query to get the IDs of deleted cases.

select id from case where isdeleted = true

Once I have the ID, then I can use workbench to execute anonymous Apex. Just put a comma separated list of Ids in the List:

Database.emptyRecycleBin(new List<Id> {'500U000000IonltIAB'});

Get Ready for Dreamforce 15

With just over a week left until the hordes descend on San Francisco, there’s a lot to prepare for. The big announcement for Dreamforce is going to be the new Lightning Experience. This new look of Salesforce is going to change everything! Rather than wait till you get to Dreamforce to begin learning about Lightning, I recommend taking a look at the new Trailhead modules. By finishing those modules, you’ll be better prepared and ready to jump into more advanced topics when you get to Dreamforce.

The Admin Trail – Migrating to Lightning Experience is best for existing admins who are interested in the impacts Lightning would have on your org. It walks you through the basics of Lightning. One of my favorite parts is the chart that compares the differences between Lightning and Classic. If you only do one thing before Dreamforce, look at this chart!

On the Developer side of things, the Developer Trail – Lightning Experience walks developers through Visualforce and Lightning Components. Unfortunately, since Lightning isn’t GA there aren’t the hands-on projects you get with a lot of other modules. One of the coolest things Salesforce is doing as part of the Lightning push is sharing design best practices. The module on the Lightning Design System is fantastic for getting an understanding of how to build pixel perfect components.

With these new Trailhead modules, you’ll be prepared for Dreamforce and ready to attend some awesome sessions!

If you are still looking for sessions (that don’t have anything to do with Lightning) to attend, here’s my shameless plug for the two sessions I’m presenting:

Writing Effective and Maintainable Validation Rules Tuesday, September 15, 12:00 – 12:40

Writing Effective and Maintainable Validation Rules Friday, September 18, 10:00 – 10:40

Apex Testing Best Practices Thursday, September 17, 4:30 – 5:10

Deploy Faster with Summer ’15 Features

Buried in the pages of the Summer ’15 release notes is a little feature that you might easily pass by. If you take advantage of this feature, then you can drastically speed up your deployments to production. This new feature allows you to choose which tests are run in a deployment.

First of all, the biggest change is that tests are only run when you are deploying Apex classes or triggers. This means that your deployments will immediately be sped up if you are only deploying objects, new fields, workflow rules, etc. If you do have Apex in your deployment package, then by default all local tests are run. Local tests are those that are not namespaced (included in a managed package).

The cool thing is that you can now make a change to your build.xml file to specify tests to be run. When you do this, only the test you specify in the build.xml file are run and Salesforce only looks at the code coverage from those tests on the code you are deploying. As long as the tests pass and the code coverage is good, then your deployment will succeed.

What does this mean in a real life situation? I ran a couple of scenarios and saw marked improvements. If I deploy a single class the old fashioned way, then tests in my org take about 30 minutes to complete. If I instead specify a specific test class, then my deployment time dropped to 2 minutes. This is huge, when you think about needing to deploy an emergency patch. You no longer need to wait for all tests to complete.

A word of caution: if you have the luxury of time, I highly recommend you run all local tests and use the quick deploy feature. This allows you to stage your release and make sure everything is working properly. Use the specific tests option only in cases where you need to get something to production fast.

Upgrade your Force.com Migration Toolkit and start getting faster deployments! Let me know how you plan on using this new feature.

Streamline Your Deployments

We had a release to production last night, and I marveled at how smoothly things went compared to the first release we did as a team. In this post, I’ll outline the critical components of building a successful release package.

1. Documentation

Before you even start work on features or bug fixes, have a system in place to document what is being asked for and how it will be used. We have a custom built set of objects in Salesforce to track this. Each feature or bug fix is assigned to a release and sprint and status is tracked as it moves through the process. We also add metadata as a related list to the features so we know what was changed. I’ve written some code that builds a package.xml based on all the items in the release. We use this package.xml file during our deployments.

2. Development Environment

Each person making changes that will go into the release should do their work in their own sandbox. By staying in your own sandbox, you have  no danger of overwriting someone else’s changes.

3. Version Control

Using version control ensures you can easily track changes back to a person and a feature request. We use a repository on Github that contains a complete snapshot of metadata. Each feature request goes in a branch that will get merged.

4. Continuous Integration

Before a feature gets merged into the release branch in Git, we test each one with CI. We use Snap-ci to do our CI. When a pull request is created, Snap does a validation build and runs all unit tests to make sure nothing is broken. If the change breaks the build, we know about it early and can fix it before it gets merged and sent on to users for testing.

5. Deployment Tool

All deployments are performed using the Ant Migration Tool. This allows for creation of a release package will all the metadata in it that we can deploy again and again to different sandboxes. We test the deploy at least three times before releasing to production.

6. Sandboxes

We use a lot of sandboxes when preparing for a release. Below are a few of the main sandboxes we use.

Staging – this is a config only sandbox used as the target of our CI process.  This sandbox is also used for user demos and basic testing by the development team.

UAT – this is a full sandbox that we use for user acceptance testing. We deploy from Staging to UAT about 2 weeks prior to the release to give users enough time to test and sign off on the changes. Important: if a user group doesn’t sign off on a change, we will pull their feature from the release.

Backup – this config only sandbox is created a day before the release and serves as a complete backup of the org’s metadata. It is easier to create a sandbox than doing a backup using Eclipse, Ant, or MavensMate. This sandbox is used in case we need to review how something worked prior to the release (aka, did that break with this release?). We can also restore quickly using change sets from that org if things go horribly wrong.

7. Quick Deploy

A recent feature Salesforce added is Quick Deploy. This allows you to do a validation deploy to production during which all tests are run. If it validates, you can click on the Quick Deploy to deploy the changes to production without having to run the tests again. The day of the release, we validate the package against prod and then wait for the designated release time to click the Quick Deploy button. This saves us so much time.