The Problem

A few weeks ago my wife, a Salesforce admin, asked me if it was possible to create a related list that filtered out inactive contacts. I explained that it’s entirely possible to do something similar, but only with Apex and Visualforce. It got me to thinking that it’s possible to write code that, well, writes the code needed to build related lists with filters. A few weeks later, I’m releasing Custom Related Lists.

No coding required.

Custom Related Lists is an unmanaged package that enables Declarative Developers and Admins to create related list Visualforce pages. You can embed these Visualforce pages on standard and custom detail page layouts using the page layout editor. They mimic the functionality of native related lists with a few additions. With Custom Related Lists, users can select and create criteria to filter records displayed in the list. Now users can create a related list of Contacts on the Account detail page that filter out inactive contacts, or contacts of a given record type. Additionally, Custom Related Lists is not bound to the 10 field limit. Custom Related Lists is capable of displaying all the fields of a child object in the list, but users should be mindful of the user experience implications that carries with it.

How it works.

This is the technical bit, and if you’re just interested in using Custom Related Lists, you might want to skip this section. Fundamentally, Custom Related Lists (CRL) (ab)uses Visualforce as a template system to abstract out the boilerplate bits of Apex and Visualforce. It consists of three Visualforce template files:

  • CRL_MetaGenCtrl – the Controller template
  • CRL_MetaGenPage – Visualforce page template
  • CRL_MetaGenTests – Apex tests for the controller

Each of these files uses the CRL_MetaGeneratorCtrl controller, which is responsible for providing the non-boilerplate bits of code. The new Related_List__c record page has been overridden to give a nice Visualforce wizard. The user selects the “master” object whose detail pages this list will display, and the “detail” object whose records will be displayed on the list. Once selected, the user can select the fields to display, as well as defining criteria filters. The wizard is intentionally dynamic; selecting the “master” object automatically determines which objects relate to it and populates the detail selection list with related objects. Once the user has specified the details, the page controller first saves the record, and generates the controller, test, and Visualforce pages needed. Generated from the templates I mentioned above, using a little-known pageReference method – getContents(). getContents renders the given Visualforce page into a string as if it were requested by a browser. This allows us to use Visualforce as a templating system. Tied to a custom controller, the templates mentioned above are rendered in Apex through getContents(), and result in Apex code with the user-selected options merged in. For example, to be included on a detail page, the Visualforce page that displays the list must extend the standard controller of the selected object. The controller has a method to generate the startPageTag which is simply written to the final Visualforce page with standard merge syntax: {!startPageTag}

Putting it in place

After the custom controller extension, test, and Visualforce page are rendered to strings, the application puts the code in place. Apex code is placed with the Tooling API and the Visualforce page in place with a standard Rest call. (I have no idea, why Visualforce can be created with a rest call, but we need the Tooling API for Apex.) I want to give a shout out to Andrew Fawcett and James Loghry for their excellent Tooling API Apex library. (Please note, that the version of the library packages with Custom Related Lists is truncated to include only enough of it to insert Apex classes.) Because of how Custom Related Lists uses the Tooling API. It’s important to note that generating the code will work in Sandboxes and Developer orgs, but is not supported in Production orgs as these require full test runs for deployment. The tooling API requires a custom remote site setting to function. This is automatically generated using the Javascript metadata API wrapper JSForce whenever you load the app. If autogeneration of the remote site setting fails for some reason, users are given instructions on creating it.

Dynamicity and Data Portability

Custom Related Lists is designed to be run for creation in a Sandbox, and to use in a Production environment. However, it’s also designed to be highly dynamic. It would be a pain to re-generate the code and change set every time we wanted to adjust what fields are displayed. To prevent that need, the generated code references a Custom Related List object record on page load. This allows admins to change the criteria and fields displayed without having to re-generate the code and deploy it. However, this also means that users would have to re-create the record in the Production org. To prevent this need, the generated code contains a JSON encoded version of the initial Related_Lists__c record. After deployment to Production, on the first display of the related list, the code will de-serialize the JSON and create the needed record. It is highly recommend that you leave sharing settings for Related_List__c records as public read.

Using Custom Related Lists

Installing Custom Related lists is slighting more complex than a standard package as it must be installed in both your Production and Sandbox orgs. Once you’ve installed it in both orgs using these links…

Once installed, the process is straightforward. First, open the Custom Related Lists app from the app selection menu.app selection This will load the apps info page which will attempt to securely create a remote site setting on your behalf. If you’re an administrator of the org, this should succeed, and you’ll see a green success menu like this.remote site setting success

If it fails, follow the instructions to manually create the needed remote site setting. Once your remote site setting is settled, you can navigate to the Custom Related List tab. crl tabThis is a standard list view for your Custom Related Lists objects.

This is a standard list view for your Custom Related Lists objects. To facilitate ease of use, I’ve overwritten the New button to utilize a custom Visualforce page that looks like this:

wizzard

Lets go through each of the input fields here and talk about what they do.

  1. Step 1: The name you provide here in Step 1 is used as the name of your Visualforce page that you’ll end up placing on a page layout. It’s good to be descriptive, but you only have 40 characters, so a good example would be something like “Active Contacts for this Account.” Short but descriptive.
  2. Step 2: This is where the fun starts. Whatever object you choose here determines everything else available to you. You want to choose the object on whose detail page layout you want to display this list. If you want to display, for instance, Active Contacts on this Account, you’d choose Account here. Custom Related Lists determines the options available to you in Step 3.
  3. Step 3: Choose the relationship you want to display. In the background, it asks the system to describe all objects that are related to your choice in Step 2, and shows you the Labels for those relationships. If you have a situation where you have multiple relationships, say a Master/Detail relationship and a Lookup relationship to the same object you must pay careful attention to choose the one you’re looking for. As an Administrator or Developer, you need to ensure you’re naming your relationships such that you can distinguish them! In our example of active contacts on this account, we’d choose Contact in Step 3.
  4. Step 4: Once you’ve selected the relationship to display, the app will load all of the relevant fields that are available for display. You can select fields on the left hand side and move them to the right, which will select them for display in your list. While standard related lists are limited to 10 fields, custom related lists are not.
  5. Step 5 is probably the most powerful and crucial step here. Unfortunately,itcan be the most confusing. Let’s start with some terminology.Criteria are the options you’re setting to filter which recordswill be displayed in your list. Constraintsare made up of a selected field, an ‘operand’ which defines the comparison method used, a Value field where you specify the valueto be compared, and afinalpicklist that lets youdetermine if this criteriashould be evaluated with AND or OR.If you’ve ever created a custom list view, thisshould be familiar. The wizard starts you off with a single criteria line, but you can add more by clicking on the Add New Constraint button. In our example of Active Contacts on Account you might select “Active” for the field name, set the operandpicklist to ‘=’ and set the value to ‘true’ (note, no quotesare needed). This would filter your list’s contents so that it only displays Contacts whose Active__c field is equal to true. Other operands available to you include ‘!=’ or not equal, as well as <, >, <= and >= or greater than, less than, less than or equal to, and greater or equal torespectively. Some example criteria to get your imagination going:
    1. RecordTypeId, =, your RecordTypeId here — would result in a related list only displaying related records of a selected record type.
    2. Email, !=, null -- Null is a special word, and in this case allows you to filter your list to exclude contacts with no email listed.
    3. CreatedDate, >=, 2005-06-15 — show only records thatwere created after June 15th, 2005.Note that you can use any of the APEX Date Literals for the value, and that you are responsible for providing the proper date format string! See here for more details!
    4. I mentioned before that you could create multiple criteria lines by clicking the Add New Constraint button. How those constraints are interpreted in relation to one another is dependent on your selection of AND or OR. For instance, you could use AND to ensure that both: RecordTypeID = your RecordTypeId, as well as lastModifiedDate >= LAST_90_DAYS criteria are met, ensuring that your list would only display records with the matching Record Type Id that were also modified in the last 90 days. If you select OR for those constraints, records with the selected Record Type Id OR who were modified in the last 90 days would be displayed.
    5. It is important to note here that you MUST have at least one constraint for Custom Related Lists to properly work. If you do not have criteria to add, use a standard related list.
  6. After clicking the Create New Custom Related List button and the page reloads, you’ll see the Generate Controller and Page button. Once you click the button, Custom Related Lists will generate the controller, the test class, and the Visualforce page.
  7. At this point, you’ve got everything you need, but only in your Sandbox org. There are three files you’ll need to include in your change set, and their filenames are listed on the final page. Deploy your change set, and then edit your page layout to include your Visualforce page and you’re set!

Important Considerations and Caveats.

This package makes several assumptions, and while they’re valid in the vast majority of cases, they’re not always going to work. While the package works hard to ensure that the fields listed for inclusion in the related list are queryable and available for use, not all of them actually are. For instance, say you’re creating a related list of notes to a given Account. The system will report that “Name” is available, but upon running it… not so much. Let’s call it a platform quirk. The good news is that most of the fields I’ve found that are affected by such quirks are not the kind of fields you’d typically want to put in such a list. The really good news, is that the related lists are fully dynamic. When the page loads, it pulls its configuration details from the Related_List__C object. If you run into an issue with a field not being available you can edit the fields on the object and reload. No code regeneration needed.

I hope y’all find this as useful, as I had a ton of fun building it. In the future I want to fix the edit screen to use the same wizard, and capture as many edge cases as possible. In the meantime, you can find the code on Github, and I’ll gladly accept pull requests and issues for feature requests. If Custom Related Lists makes it into your org, and saves you time and energy, feel free to hit that tip button on the left.

Trailhead.

Trailhead is by far and away my favorite learning tool for Salesforce development. The combination of guided tutorials with hands-on, in-org development is unbeatable. On top of this, the guided tutorials have built-in direct feedback to help. Until recently, the state of the art for teaching programming languages was books. The best we had for checking our work was compiler and interpreter errors. I’ve waxed philosophical about Trailhead before, but it’s unparalleled as a teaching tool. Recently a Lightning Dev week participant asked me what my favorite Trailhead module was? After some consideration, I think my favorite module is…

Apex Testing.

trailhead_apexTestingI spend a lot of time on the developer forums and Salesforce Stack Exchange. I think it’s safe to say that the majority of questions are about testing. There’s the classic “will you write my tests for me.” The philosophical “why must I write unit tests?” But my favorite is still, how can I increase my test coverage for this code? Trailhead’s Apex Testing module, while it doesn’t cover everything, is a great start.

The module’s components.

The Apex Testing module has three components that build on each other. First, it starts with an overview of unit testing basics like assertions. This component tops off with a practical test — write a unit test for a given class. To pass the challenge, you have to meet 100% test coverage. The challenge of 100% test coverage reinforces several core ideas. Most importantly it enforces the practice of testing all the logical paths in your code.

Unit Testing Apex Triggers.

Because Triggers execute in response to DML events, unit tests for triggers have to contain assertions and DML statements. While orgs have to maintain 75% aggregate average code coverage, all triggers have to have some coverage. This has the practical effect of a many more testing questions related to Triggers. Learning to test triggers in Trailhead serves not just to train developers but to advance the community. It does this by decreasing the number of routine “how do I write a test for this trigger?” questions on the forums.

Creating Test Data.

Of all the components in the Trailhead Apex Testing module I find the last one most valuable. In this last component readers learn why it’s important to create your own test data. This is more than just a practical matter and the key to why this is a hidden gem. Testing your code is arguably more important than actually writing it. While a majority of us wouldn’t neglect objects or other code dependencies; Data dependencies are often overlooked. Learning to write proper tests means learning to write code that fulfills all dependencies. By fulfilling all the dependencies and writing proper tests, developers gain the confidence that their test is valid not only today, but next week and next release!

A good three base hit.

Trailhead’s Apex Testing covers three of the most important aspects of unit Testing. While Trailhead takes the time to teach the basics of unit testing I believe it misses two key facets. First, and most importantly, it doesn’t address the importance testing different users and scenarios. Specifically, I want Trailhead to teach developers to write tests that:

  1. Test the “expected” behavior — so-called “positive” test cases. These tests pass in expected input and test for expected output. One positive test case for each logical branch.
  2. Test expected Exceptions — so-called “Negative” test cases. These tests pass in invalid or otherwise faulty data into the unit of code. Negative tests assert that the code threw an exception. Bonus points for tests that assert a specific type of exception and it’s message.
  3. Test the code with various user roles and permissions. Can the code handle execution with a non-sysadmin?

Each of these test types safeguards against common exception cases. By testing more of these common cases, we gain more confidence in the robustness of our code. Perhaps Trailhead will expand to teach these three test types. (Dear Trailhead team, if you’d like help with that, tweet me!)

Secondly, I wish Trailhead also discussed HTTP callout tests. More and more of our work as Salesforce developers involves integrations. These integrations often take the form of api integrations through HTTP callouts. Testing callouts requires knowledge of the HttpCalloutMock interface and using the Test.startTest() and Test.stopTest() methods.

Regardless of these two sticky bits, I think this module is the best one out there. Testing is one of those key skills that every Salesforce developer has to master. Trailhead provides not only knowledge transfer but skill practice and evaluation — a combination that can’t be beat — especially for testing.

Salesforce Communities sometimes have to be Debugged.

Recently I had the opportunity to do some communities work. On the whole, I love the communities product. From an end-user perspective it can’t be beat. As a developer, but, I’ve hit a few snags debugging Visualforce pages in communities. During normal Visualforce development, you can rely on the platform to surface errors. Usually this takes the form of a nice ugly error message. Now ugly error messages are the epitome of terrible user experiences. So it’s understandable that Salesforce would prevent them from appearing to users.

Debugging Communities with uglyErrorMessage

Behold, an ugly error message in it’s uninformative native habitat!

Unfortunately, Salesforce replaces Visualforce errors with a different, but far less informative error message. This error displays only for Visualforce errors – not Apex errors. In fact, two conditions must be met for this kind of error. First, a page’s controller or controller extension(s) must instantiate without error. Secondly, there must be some kind of rendering error. What do I mean by “rendering error”? Well, in my case it was a view state size error. When these types of errors happen, Salesforce hides the error behind this lovely message.

When I first started experiencing this bug, I started with the usual debugging techniques. I tried a few different users. I tried adding users to debug logs. I made sure that logs were appearing in the dev console and read every line. I saw my controller firing up and completing without a single error. Yet the error page plagued me. After some discussion with the IRC #salesforce community I discovered a method on the PageReference class called getContent. getContent() returns the rendered content of the page, including error messages. Most importantly, getContent() returns errors rendered at the Visualforce level. This allows us to capture the error before Salesforce neatly hides our error. It’s possible to construct a page that attempts to render the content of any other Visualforce page in a try/catch block. When the page catches an error, it’s displayed.

Debugging Communities with a Visualforce wrapper

To help others with debugging communities based Visualforce errors, I’ve developed a reusable Visualforce page called CommunityDebugger, and its corresponding controller CommunityDebbugerCtrl. Here’s the controller code:

And the Visualforce page:

To use this page to debug a community page:

  1. Deploy the controller and page to your sandbox or developer org. You shouldn’t deploy this to production.

  2. Visit your silently failing Community url, say cs4.force.com/awesomeCommunity/failingPage?param1=foo&param2=theDoctor

  3. Prepend “CommunityDebugger?page=” before the your failing page. Like this: cs4.force.com/awesomeCommunity/CommunityDebugger?page=failingPage&param1=foo&param2=theDoctor

  4. When the page loads, your error will be rendered for you to see, like this:

System.VisualforceException : Id value is not valid for the User standard controller : Class.CommunityDebuggerCtrl.fetchFailingPage: line 23, column 1

And that, my fellow developers, is an error message you can act on. For the record, the bug that started this all? My view state was too big. Transient FTW.

I’m a PC. I’m a Mac. I’m Linux

Back in the day there were really on two or three holy wars that coders inevitably got dragged into. First there is the war of the editors: Vi(m) V. Emacs. (Sublime FTW.) Then there’s Windows V. Mac V. Linux V. *BSD. Finally, it seems that everyone has their own post on why their favorite programming language is better than X.

After my last post, I received a number of responses on twitter and here via comments about naming things like classes, objects and methods. After some conversation with other developers, I’ve discovered a new (cold) holy war among developers — Naming conventions.

A Rose Method by any other name…

There are a few well-known naming conventions for variables – Hungarian variable notation comes to mind. There are several frameworks and languages that have specific conventions as well. Rails (well, more specifically Active Record) has class and model conventions describe how you name objects and their controllers. In both cases, the conventions are there to help developers understand the meaning and purpose behind what their referring too. Hungarian notation prefixes a logical type identifier to the variable name. Rails’ conventions illustrate whether you’re dealing with an object, a database table or a model. In Salesforce, however, it seems we’re much more loosey-goosey with our naming schemes. I polled a number of developers I respect about how they named classes and method and by far, the most thought out answer I received was:

Carefully. ~Akrikos

To be honest, at first I thought his answer was a bit flippant, but he followed up by saying: “Every time I’ve named something poorly I’ve regretted it. Especially in the Salesforce world where there’s such a high cost to changing the name of something.” He’s right, of course, that there’s a high price to pay for renaming a class in Salesforce. The platform demands integrity and renaming something means touching everywhere it’s used. So then, what’s in a name?

What’s in a name?

It stands to reason then, that regardless of what conventions you adopt, you should strive to enforce them 100% consistently.

Naming a method or a class is all about assigning meaning. Conveying meaning in a limited number of characters is all about conventions. Conventions provide consistency that enable at-a-glance understanding. It stands to reason then, that regardless of what conventions you adopt, you should strive to enforce them 100% consistently. Here are some conventions — in no particular order, that I think you should adopt:

  1. Filenames should have standardized endings. This helps you quickly show the purpose of the file, and its class
    1. Test classes end in Tests.
    2. Custom Visualforce Controllers end in Ctrl
    3. Custom Visualforce Controller Extensions end in CtrlExt
  2. Bias towards longer descriptive names and not shorter ones: ThisMethodDescribesWhatItDoes() v. magic()
  3. Put reusable utility code in a utils or lib class. i.e. “CommonContactUtilities”
  4. Group related code together with an “internal namespace”. For instance, if you’ve developed a set of Visualforce pages and Extensions for feature XYZ internally namespace them like:
    1. XYZ_CustomAccountDemoCtrlExt
    2. XYZ_VisualForcePageOfAwesome
    3. XYZ_CustomAccountDemoCtrlExt_Tests
  5. Async classes should include in their name the class they’re scheduling or batching

Homage to Sandi Metz

Sandi Metz, Ruby Hero and Author of Practical Object Oriented Design in Ruby

A year or so ago, Ruby Hero and author of Practical Object-Oriented Design in Ruby Sandi Metz gave us her four rules of Ruby Development. As stated, her four rules are:

  1. Classes can be no longer than one hundred lines of code.
  2. Methods can be no longer than five lines of code.
  3. Pass no more than four parameters into a method. Hash options are parameters.
  4. Controllers can instantiate only one object. Therefore, views can only know about one instance variable and views should only send messages to that object (@object.collaborator.value is not allowed).

While her rules are rather specific to Ruby development, I believe the ideas behind them are fairly universal and useful. With that in mind, here are a set of rules for Apex development, along with the rationalization behind it.

My highly opinionated rules for Apex SimplicityastroSays2

  1. Classes can be no longer than 300 lines of code. — I took three classes from production Apex projects and ported the code to idiomatic Ruby. Each of my Apex classes used aproximately three times the number of lines that the Ruby code took, hence 300 lines. Putting a cap on the number of lines has a number of benefits, but perhaps the biggest is found by enforcing a clarity of purpose on the class. Recently, I had the opportunity to work with a 2k line class “Coupon”. It handled five types of discounts. Breaking those five discounts into five classes helps convey what class had responsibility for what.
  2. 20 lines per method — This is easily the most contentious rule. The primary benefit of following this rule is that your code will necessarily be simpler. Nested if statements, and long blocks of code for edge cases are now tucked away in other, more tightly focused — and more easily tested — methods. Like Thoughtbot’s implementation of Metz’s rules, I think this could use some explaination though, as not everything makes sense as a ‘line’. Conditional logic keywords like if/else each count as a line. The line constraint will also likely reduce your use of else if() constructs keeping your code simpler as well! So why 20 lines? Well Ruby has an implicit return structure, whereas Apex requires explicit return statements adding at least one extra line per method. Couple that with a generally more verbose language and I felt like 20 was the sweet spot. It’s a fairly arbitrary choice, I admit but in some testing I’ve found that I can usually get my methods into 20 lines (not counting comments. You are commenting right?)
  3. Only four method arguments per method — First, let me state an exception to this rule. Factory methods for producing test data are immediately exempt from this rule. For instance, a factory method for returning an Order may require passing in: a User, an Account, a Contact, an Opportunity as well as… well you get the idea. Unlike test methods, most ‘live’ methods accept parameters for one of two reasons: direct manipulation of data or conditional logic. Again, simplicity is the real reason and winner here. Limiting each method to no more than four incoming parameters forces you to have different methods for different conditional branches making your methods are short, concise and tightly focused.
  4. Visualforce Controllers can only talk to a single instance variable. I admit, I have a hard time following this one. The idea here, is to expose the entirety of your data through a single wrapper object. This forces architectural changes on down the line. Your controller or controller extension becomes focused not on gathering data, but preparing it for the view. This has a number of benefits, but code simplicity and testability are the best. Note, this doesn’t include controller methods, just the data being exposed on the page.

If you’re sensing an underlying theme to these, it’s simplicity – keeping the code as simple as possible. These rules help enforce simplicity. Of course sooner or later we’ll hit a class with 350 lines and no good refactoring path. And thats ok too, Break the rules when you have to, not just because you can.

I’ve been using the Salesforce Mobile SDK for a few years now. Every version has been a big improvement. However, the latest release — version 3.1 has a couple of noteworthy additions. So noteworthy that I want to specifically address them. While there are some technical features included — it’s now a cocoapod! — there are two non-tehcnical features I want to highlight.

Unified Application Architecture in the Mobile SDK

In their own words, Salesforce has:

unified the app architecture so that apps built with the latest SDK – hybrid or native – now have access to the same core set of functionality regardless of their target platform. All the libraries, all the APIs, and all the major mobile building blocks have consistent implementations, while at the same time, provide full access to the host operating system.

To break that down, what they’re saying in their understated way is that you can now write apps for Android, and iOS using your choice of:

  • Objective-C or Swift (with a bit more work) on iOS.
  • Java or C (with a bit more work) on Android.
  • Html5, Css andUnified Architecture FTW Javascript for both iOS and Android.

Theoretically, if you’re willing to put in some extra work, you could place the JS within an Windows 8.x phone container. Enabling hybrid Salesforce connected apps on Windows 8.x. What’s most impressive about this platform feature parity, is that all the building blocks of a connected Salesforce mobile application have consistent implementations. This allows for an unprecedented level of flexibility for developers. Developers who can now make platform choices based on business needs (I need to support iOS and Win phone 8.1) rather than what features are available (I need Smartstore, so I have to use the JS/Hybrid platform).

Docs and Examples from the Mobile SDK

The second feature of the new SDK version that I want to highlight is actually near and dear to my heart. For me, there are two equally fistsimportant forces that drive my understanding and adoption, of a new API, SDK or technology: Documentation and Example code.

Docs are a coders best friend, providing all the nitty-gritty details of how every individual function works. The Mobile SDK has a brilliant set of documentation (iOS docs are here). Without these, using the SDK would be a black-box nightmare.

On the other hand(or fist), Example code is a Noobies best friend. When you’re starting out with a new API or SDK, you need to see what is happening. Indeed, you need to see what to do more than how to do. ‘Do I login first thing? or show a settings dialog?’ Example code leads to the Eureka of ‘Oh, I see — I present the login view first.’ Moreover, example code exposes new users to what methods and functions are available! Included in version 3.1 of the SDK we find iOS and Android example applications. More importantly, we also find a hybrid (html, css, js) example. Additionally, the SDK has related examples using Polymer. Perhaps most interestingly, the developer evangelism team has example code using Angular / Ionic!

While each release of the SDK has brought new and exciting features version 3.1 brings not only features but a level platform development field and examples to bring new developers up to speed quickly. Now if only they’d support Rubymotion.

trailheadIf you’ve not yet heard about Trailhead, click here. I’ll wait. Back? Great. Trailhead is awesome, and I’ve been a big fan since it was released at Dreamforce ‘14. It’s got modules for both the clicking and the coding developers among us. Regardless of your development style, the mix of videos, how-to’s and exercises are helpful to learn and sharpen your skills. About two weeks ago, I finished all the available modules, and tweeted out that I was finished. At the time I was promised more modules and this morning I woke up to two wholly new modules and two modules with new exercises!

trailhead data security

Trailhead Data Security

Data Security is the first new module. It teaches users the finer points of Field Level Security (FLS), Sharing Rules, Role Hierarchy, and related information. Perhaps the most important section is the overview of the module. I don’t want to ruin the fun, but I will say you might want to print this off and post it on your wall: a handy infographic on data security! It should be pointed out that Data Security is possibly the single most important and complex topic covered by Trailhead, and it’s critical we all become experts on this. Also, for the record, forcing users to use a hardware token is only an organizational security feature in my head.

trailhead change management

Trailhead Change Management

Trailhead Change Management is the second new module released today. It discusses the finer points of using sandboxes, change sets and the overall workflow recommended for Salesforce feature development. While Trailhead is aimed at developers, I wish this module was somehow required homework for managers and budget creators who argue against providing developers sandboxes! Build, Test, Deploy! Build in a sandbox, deploy to production!

In addition to the two new modules, there are new challenges associated with the testing and apex modules. Interestingly, the Trailhead site now shows a preview of things to come with modules for:

  1. Asynchronous Apex
  2. Apex Integration Services
  3. Visualforce & JavaScript
  4. App Deployment

I, for one, look forward to finishing up the Data Security and Change Management modules while they prepare the new Apex modules! You can get started with Trailhead by clicking here!

A while back I stumbled across a situation where I needed to do a visualforce mail merge, but I didn’t want to send the email. Unfortunately, there’s no built in way to do that. Salesforce’s Visualforce merge code doesn’t give you a “getter” for the merge result. Instead, the normal workflow looks like this.

    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[]{'theDoctor@who.com'};
    mail.setToAddresses(toAddresses);
    mail.setUseSignature(this.useSig);
    mail.setSaveAsActivity(this.saveActivity);
    mail.setSenderDisplayName(this.senderDisplayName);
    mail.setTargetObjectId(targetObjectId);
    mail.setTemplateId(templateId);
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});

In fact, there’s not even a .merge() method exposed in Apex. The merging happens as part of Messaging.sendEmail();

However, after some research I discovered that PJC over on Stackexchange had figured out that a DB savepoint could be (ab)used to grab the template contents after merging. This is Neat(c).

Fast forward a few months, (LifeWithRyan)[http://www.sudovi.com/] and I are talking on IRC about this same problem. We agreed to both blog our solutions. His is here: (When an Email Template just isn’t enough)[http://www.sudovi.com/when-an-email-template-just-isnt-enough/] I decided to wrap the method I found up in a reusable class: MailUtils.cls. Mailutils offers a single static method. getMergedTemplateForObjectWithoutSending(Id targetObjectId, Id templateId, Boolean useSig, Boolean saveActivity, String senderDisplayName) That takes the work out of this. It returns a Map, with the following keys:
textBody: Merged text body
htmlBody: Merged html version
subject: Subject line of the email

Here’s MailUtils.cls in its full ‘glory’:

public class mailUtils {
  public class mailUtilsException extends exception {}

  public Boolean useSig {get; private set;}
  public Boolean saveActivity {get; private set;}
  public String senderDisplayName {get; private set;}

  public mailUtils(Boolean useSig, Boolean saveActivity, String senderDisplayName){
    this.useSig = usesig;
    this.saveActivity = saveActivity;
    this.senderDisplayName = senderDisplayName;
  }

  // Derived from: 
  // http://salesforce.stackexchange.com/questions/13/using-apex-to-assemble-html-letterhead-emails/8745#8745
  public Messaging.SingleEmailMessage MergeTemplateWithoutSending(Id targetObjectId, Id templateId) {
    Messaging.reserveSingleEmailCapacity(1);
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    // Intentionally set a bogus email address.
    String[] toAddresses = new String[]{'invalid@emailaddr.es'};
    mail.setToAddresses(toAddresses);
    mail.setUseSignature(this.useSig);
    mail.setSaveAsActivity(this.saveActivity);
    mail.setSenderDisplayName(this.senderDisplayName);
    mail.setTargetObjectId(targetObjectId);
    mail.setTemplateId(templateId);

    // create a save point
    Savepoint sp = Database.setSavepoint();
    // Force the merge of the template.
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    // Force a rollback, and cancel mail send.
    Database.rollback(sp);

    // Return the mail object
    // You can access the merged template, subject, etc. via:
    // String mailTextBody = mail.getPlainTextBody();
    // String mailHtmlBody = mail.getHTMLBody();
    // String mailSubject = mail.getSubject();
    return mail;

  }

  public static Map<String,String> getMergedTemplateForObjectWithoutSending(Id targetObjectId, Id templateId, Boolean useSig, Boolean saveActivity, String senderDisplayName) {
    Map<String,String> returnValue = new Map<String,String>();
    mailUtils mu = new mailUtils(useSig, saveActivity, senderDisplayName);
    Messaging.SingleEmailMessage mail = mu.MergeTemplateWithoutSending(targetObjectId, templateId);
    returnValue.put('textBody', mail.getPlainTextBody());
    returnValue.put('htmlBody', mail.getHTMLBody());
    returnValue.put('subject', mail.getSubject());
    return returnValue;
  }

}

I never thought I’d be the kind of person to “do” a 5k. In fact, had you asked me a month ago, I’d have told you that Americans don’t understand the Metric system, and that 5k runners were clearly invading Canadians in disguise. And yet, two weekends ago I found myself standing at the starting line of the Santa Paws 5k surrounded by 300 invading Canadians and their four-legged best friends. Santa Paws is the annual fundraiser for the Wake SPCA, here in North Carolina. Of course, I couldn’t just walg (walk-jog) the 5k, I had to turn it into an excuse to play with new technology!

The Quantified Self.

For awhile now I’ve been fascinated by the idea of the Quantified Self. In short, the idea is to log one’s activities, locations and events. The hope is that more data can lead to better decisions. Some of this has been going on for decades. Keeping one’s day-planner, or diary updated is likely the analog beginnings of the Quantified Self. The innovation of our generation is found in passive collection. Put a Fitbit, Up (or soon, Apple Watch) on your wrist and your daily sleep and activity is automatically recorded. In the age smartphones with motion co-processors and clever apps we can even move beyond automatically gathering data, to proactively prompting actions. Everyday, ’round about 5pm RunKeeper lovingly(annoyingly?) tells me “Remember, you used to think this was a fine time to go walk? Want to go for one now?” Our access to technology has raised the bar from passive collection of data, to actively prompting and encouraging better decisions. (And yes, even I have to admit that more activity is a better decision for me.)

The Problem

Kevin and Lilo rest after the finish of the SantaPaws 5k

Kevin and Lilo rest after the finish of the SantaPaws 5k

Lilo is my adorable 45lb Carolina dog. She’s ferociously smart, loves Babyfriar and is the secret to cheap, boundless energy — if we could only figure out how to harness it. I’ve worried that she’s not as active as she needs to be because her brothers are decidedly lower energy critters. She needs more exercise. Right about the time I signed up to do Santa Paws with Lilo, I found out about Whistle, wifi enabled ‘Fitbit’ for dogs. Whistle uses a Bluetooth connection to your phone to identify who the Pup is with during activities and can differentiate between a walk, playtime and sleeping-in-the-most-uncomfortable-looking-position-on-the-couch. A quick trip to the pet store and Lilo was Whistle’d. Not only are we quantifying ourselves, but our best friends as well. Indeed, with the RunKeeper app providing information like distance walked, and the current and average pace while recording GPS locations; it’s possible to not only quantify any given walk, but also use that data to, for instance, slowly increase pace and distance for training purposes. The problem, however, is that the RunKeeper data is siloed off in the RunKeeper app while the Whistle data is hidden off inside the Whistle app.

Enter Salesforce

I believe Salesforce provides an ideal platform for self quantification. It’s api’s provide a rich environment for integrating and aggregating data from a myriad of sources. And so a project was born: A real-time updating map display of Lilo and my progress on the 5k course with GPS data from RunKeeper, step information from Fitbit and activity information from Whistle.

Building it out

As with many a side project, the design was simple on paper, but proved rather challenging to implement. I wanted an app that would:

  • Collect data from Fitbit
  • Collect data from RunKeeper
  • Collect data from Whistle
  • Display the data on a Map
  • Update the map in realtime as new measurements are recorded by RunKeeper
  • Expose all this in a nice way to my supporters so they could see the race progress.

The design

My starting, back of the napkin design had me using the Streaming api to deliver updates to a public, authentication-free force.com site. Unfortunately, I quickly discovered I can’t use the streaming api on an unauthenticated site — sadness — so instead I wired it to periodically pull new records via javascript. I also discovered that, despite my best intents, hooking Runkeeper, Fitbit and Whistle all up was a too-tall task for the 6 days I gave myself between hatching the thought and actually walking the 5k. What I ended up with was an app that received, and interpreted GPS and walk data from RunKeeper and displayed it in near-realtime on a map. You can view a replay of our 5k walk here.

The data is populated from RunKeeper via a Heroku based Rails middleware app. As I have time, I’ll flesh that out with data from Fitbit annotating each marker with the number of steps taken since the last marker. Unfortunately, Whistle has declined (as of yet) to publicize an API, leading to a rather hacktastic, unofficial api that is currently broken (or my charles-proxy-fu is weak.)

Apophenia

Ever look at a cloud and think “Oh, Hey, it’s a [Star Destroyer | Tardis | Puppy eating a Tardis! ]?” If so, you’ve experienced apophenia; the experience of identifying patterns or meaning in seemingly random data. Our brains are really good at finding such patterns, but the information isn’t always presented in ways we can easily process. This is where analytics steps in, helping us visualize data and in so doing, understand what it all means.

This is the real reason the Salesforce1 is such a great aggregation platform. It’s suite of analytics tools — from reports, dashboards and the analytics api that can power D3 based visualizations like the one’s Christophe Coenraets has blogged about — are unparalleled. After we’ve moved to 30 hour days, and I have more time, I’ll update the maps page to show some D3 based analytics showing the number of steps and elevation gain. That’s a start on visualizing how my pace slows per % of grade uphill and demonstrates that running downhill after your dog is still faster than tripping and rolling downhill after your dog.