def diff_to_html(cls, details):
        changes = []
        if not details:
            return ''
        def _frame(value):
            if isinstance(value, dict) and '_str' in value:
                return value['_str']
            elif isinstance(value, list):
                return ', '.join([_frame(v) for v in value])
            return str(value)
        fields = sorted(details.get('additions', {}))
        for field in fields:
            new_value = _frame(details['additions'][field])
            if isinstance(new_value, list):
                new_value = ', '.join([_frame(v) for v in new_value])
            change = cls._templates['add'].format(
                field=field,
                new_value=new_value
                )
            changes.append(change)
        fields = sorted(details.get('updates', {}))
        for field in fields:
            original_value = _frame(details['updates'][field][0])
            if isinstance(original_value, list):
                original_value = ', '.join([_frame(v) for v in original_value])
            new_value = _frame(details['updates'][field][1])
            if isinstance(new_value, list):
                new_value = ', '.join([_frame(v) for v in new_value])
            change = cls._templates['update'].format(
                field=field,
                original_value=original_value,
                new_value=new_value
                )
            changes.append(change)
        fields = sorted(details.get('deletions', {}))
        for field in fields:
            original_value = _frame(details['deletions'][field])
            if isinstance(original_value, list):
                original_value = ', '.join([_frame(v) for v in original_value])
            change = cls._templates['delete'].format(
                field=field,
                original_value=original_value
                )
            changes.append(change)
        return '\n'.join(changes)