(feat) email alarms now have pretty formatting (fixes #805)
parent
dbf5039011
commit
7d396a51f5
|
@ -22,6 +22,8 @@ vtodo_class2 = "(Confidential task)";
|
||||||
"location_label" = "Location";
|
"location_label" = "Location";
|
||||||
"summary_label" = "Summary";
|
"summary_label" = "Summary";
|
||||||
"comment_label" = "Comment";
|
"comment_label" = "Comment";
|
||||||
|
"organizer_label" = "Organizer";
|
||||||
|
"attendee_label" = "Attendee";
|
||||||
/* Invitation */
|
/* Invitation */
|
||||||
"Event Invitation: \"%{Summary}\"" = "Event Invitation: \"%{Summary}\"";
|
"Event Invitation: \"%{Summary}\"" = "Event Invitation: \"%{Summary}\"";
|
||||||
"(sent by %{SentBy}) " = "(sent by %{SentBy}) ";
|
"(sent by %{SentBy}) " = "(sent by %{SentBy}) ";
|
||||||
|
|
|
@ -43,6 +43,7 @@ Appointments_OBJC_FILES = \
|
||||||
SOGoAptMailICalReply.m \
|
SOGoAptMailICalReply.m \
|
||||||
SOGoAptMailUpdate.m \
|
SOGoAptMailUpdate.m \
|
||||||
SOGoAptMailReceipt.m \
|
SOGoAptMailReceipt.m \
|
||||||
|
SOGoAptMailReminder.m \
|
||||||
\
|
\
|
||||||
SOGoEMailAlarmsManager.m \
|
SOGoEMailAlarmsManager.m \
|
||||||
\
|
\
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* SOGoAptMailReminder.h - this file is part of SOGo
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOGOAPTMAILRECEIPT_H
|
||||||
|
#define SOGOAPTMAILRECEIPT_H
|
||||||
|
|
||||||
|
#import "SOGoAptMailNotification.h"
|
||||||
|
|
||||||
|
@class NSArray;
|
||||||
|
@class NSString;
|
||||||
|
@class iCalPerson;
|
||||||
|
|
||||||
|
|
||||||
|
@interface SOGoAptMailReminder : SOGoAptMailNotification
|
||||||
|
{
|
||||||
|
NSArray *attendees;
|
||||||
|
iCalPerson *currentRecipient;
|
||||||
|
NSString *calendarName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setAttendees: (NSArray *) theAttendees;
|
||||||
|
- (void) setCalendarName: (NSString *) theCalendarName;
|
||||||
|
|
||||||
|
- (NSString *) aptSummary;
|
||||||
|
- (NSString *) aptStartDate;
|
||||||
|
- (NSString *) calendarName;
|
||||||
|
- (iCalPerson *) organizer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* SOGOAPTMAILRECEIPT_H */
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* SOGoAptMailReminder.m - this file is part of SOGo
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSCharacterSet.h>
|
||||||
|
|
||||||
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||||
|
#import <NGObjWeb/WOResponse.h>
|
||||||
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalEvent.h>
|
||||||
|
#import <NGCards/iCalPerson.h>
|
||||||
|
|
||||||
|
#import <SOGo/NSDictionary+Utilities.h>
|
||||||
|
#import <SOGo/NSObject+Utilities.h>
|
||||||
|
#import <SOGo/NSString+Utilities.h>
|
||||||
|
#import <SOGo/SOGoUserManager.h>
|
||||||
|
#import <SOGo/SOGoDateFormatter.h>
|
||||||
|
#import <SOGo/SOGoUser.h>
|
||||||
|
|
||||||
|
#import "SOGoAptMailReminder.h"
|
||||||
|
|
||||||
|
static SOGoUserManager *um = nil;
|
||||||
|
static NSCharacterSet *wsSet = nil;
|
||||||
|
|
||||||
|
@implementation SOGoAptMailReminder
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
|
{
|
||||||
|
if (!um)
|
||||||
|
um = [SOGoUserManager sharedUserManager];
|
||||||
|
|
||||||
|
if (!wsSet)
|
||||||
|
wsSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
|
attendees = nil;
|
||||||
|
currentRecipient = nil;
|
||||||
|
calendarName = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[attendees release];
|
||||||
|
[calendarName release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setupValues
|
||||||
|
{
|
||||||
|
[super setupValues];
|
||||||
|
|
||||||
|
[values setObject: [self aptStartDate]
|
||||||
|
forKey: @"StartDate"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) getBody
|
||||||
|
{
|
||||||
|
NSString *body;
|
||||||
|
|
||||||
|
if (!values)
|
||||||
|
[self setupValues];
|
||||||
|
|
||||||
|
body = [[self generateResponse] contentAsString];
|
||||||
|
|
||||||
|
return [body stringByTrimmingCharactersInSet: wsSet];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setAttendees: (NSArray *) theAttendees
|
||||||
|
{
|
||||||
|
ASSIGN (attendees, theAttendees);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) attendees
|
||||||
|
{
|
||||||
|
return attendees;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setCurrentRecipient: (iCalPerson *) newCurrentRecipient
|
||||||
|
{
|
||||||
|
ASSIGN (currentRecipient, newCurrentRecipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (iCalPerson *) currentRecipient
|
||||||
|
{
|
||||||
|
return currentRecipient;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setCalendarName: (NSString *) theCalendarName
|
||||||
|
{
|
||||||
|
ASSIGN (calendarName, theCalendarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) calendarName
|
||||||
|
{
|
||||||
|
return calendarName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) aptSummary
|
||||||
|
{
|
||||||
|
NSString *s;
|
||||||
|
|
||||||
|
if (!values)
|
||||||
|
[self setupValues];
|
||||||
|
|
||||||
|
s = [self labelForKey: @"Reminder: \"%{Summary}\" - %{StartDate}"
|
||||||
|
inContext: context];
|
||||||
|
|
||||||
|
return [values keysWithFormat: s];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) getSubject
|
||||||
|
{
|
||||||
|
return [[[self aptSummary] stringByTrimmingCharactersInSet: wsSet] asQPSubjectString: @"utf-8"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) _formattedUserDate: (NSCalendarDate *) date
|
||||||
|
{
|
||||||
|
SOGoDateFormatter *formatter;
|
||||||
|
NSCalendarDate *tzDate;
|
||||||
|
SOGoUser *currentUser;
|
||||||
|
|
||||||
|
currentUser = [context activeUser];
|
||||||
|
|
||||||
|
tzDate = [date copy];
|
||||||
|
[tzDate setTimeZone: viewTZ];
|
||||||
|
[tzDate autorelease];
|
||||||
|
|
||||||
|
formatter = [currentUser dateFormatterInContext: context];
|
||||||
|
|
||||||
|
if ([apt isAllDay])
|
||||||
|
return [formatter formattedDate: tzDate];
|
||||||
|
else
|
||||||
|
return [NSString stringWithFormat: @"%@, %@",
|
||||||
|
[formatter formattedDate: tzDate],
|
||||||
|
[formatter formattedTime: tzDate]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) aptStartDate
|
||||||
|
{
|
||||||
|
return [self _formattedUserDate: [apt startDate]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) aptEndDate
|
||||||
|
{
|
||||||
|
return [self _formattedUserDate: [(iCalEvent *) apt endDate]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (iCalPerson *) organizer
|
||||||
|
{
|
||||||
|
return [apt organizer];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -13,4 +13,4 @@ ADDITIONAL_LIB_DIRS += \
|
||||||
-L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \
|
-L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \
|
||||||
-L../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ -lGDLContentStore \
|
-L../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ -lGDLContentStore \
|
||||||
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -lNGCards \
|
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -lNGCards \
|
||||||
-lEOControl -lNGStreams -lNGMime -lNGExtensions -lNGObjWeb
|
-lEOControl -lNGStreams -lNGMime -lNGExtensions -lNGObjWeb -lWEExtensions
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#import <NGMail/NGMimeMessage.h>
|
#import <NGMail/NGMimeMessage.h>
|
||||||
|
|
||||||
#import <NGCards/iCalAlarm.h>
|
#import <NGCards/iCalAlarm.h>
|
||||||
|
#import <NGCards/iCalEvent.h>
|
||||||
|
|
||||||
#import <SOGo/NSCalendarDate+SOGo.h>
|
#import <SOGo/NSCalendarDate+SOGo.h>
|
||||||
#import <SOGo/NSString+Utilities.h>
|
#import <SOGo/NSString+Utilities.h>
|
||||||
|
@ -37,9 +38,19 @@
|
||||||
#import <SOGo/SOGoMailer.h>
|
#import <SOGo/SOGoMailer.h>
|
||||||
#import <SOGo/SOGoProductLoader.h>
|
#import <SOGo/SOGoProductLoader.h>
|
||||||
#import <SOGo/SOGoUser.h>
|
#import <SOGo/SOGoUser.h>
|
||||||
|
#import <SOGo/SOGoUserManager.h>
|
||||||
|
#import <SOGo/NSDictionary+Utilities.m>
|
||||||
|
#import <SOGo/NSObject+Utilities.h>
|
||||||
|
#import <SOGo/SOGoUserFolder.h>
|
||||||
#import <Appointments/iCalEntityObject+SOGo.h>
|
#import <Appointments/iCalEntityObject+SOGo.h>
|
||||||
#import <Appointments/iCalPerson+SOGo.h>
|
#import <Appointments/iCalPerson+SOGo.h>
|
||||||
#import <Appointments/SOGoEMailAlarmsManager.h>
|
#import <Appointments/SOGoEMailAlarmsManager.h>
|
||||||
|
#import <Appointments/SOGoAppointmentFolder.h>
|
||||||
|
|
||||||
|
#import <NGObjWeb/WOApplication.h>
|
||||||
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||||
|
#import <Appointments/SOGoAptMailReminder.h>
|
||||||
|
#import <WEExtensions/WEResourceManager.h>
|
||||||
|
|
||||||
#import "SOGoEAlarmsNotifier.h"
|
#import "SOGoEAlarmsNotifier.h"
|
||||||
|
|
||||||
|
@ -81,14 +92,14 @@
|
||||||
|
|
||||||
- (NGMutableHashMap *) _headersForAlarm: (iCalAlarm *) alarm
|
- (NGMutableHashMap *) _headersForAlarm: (iCalAlarm *) alarm
|
||||||
withOwner: (SOGoUser *) owner
|
withOwner: (SOGoUser *) owner
|
||||||
|
withSubject: (NSString *) subject
|
||||||
{
|
{
|
||||||
NGMutableHashMap *headers;
|
NGMutableHashMap *headers;
|
||||||
NSString *dateString, *subject, *fullName, *email;
|
NSString *dateString, *fullName, *email;
|
||||||
NSDictionary *identity;
|
NSDictionary *identity;
|
||||||
|
|
||||||
headers = [NGMutableHashMap hashMap];
|
headers = [NGMutableHashMap hashMap];
|
||||||
|
|
||||||
subject = [[alarm summary] asQPSubjectString: @"utf-8"];
|
|
||||||
[headers addObject: subject forKey: @"Subject"];
|
[headers addObject: subject forKey: @"Subject"];
|
||||||
dateString = [[NSCalendarDate date] rfc822DateString];
|
dateString = [[NSCalendarDate date] rfc822DateString];
|
||||||
[headers addObject: dateString forKey: @"Date"];
|
[headers addObject: dateString forKey: @"Date"];
|
||||||
|
@ -96,11 +107,11 @@
|
||||||
[headers addObject: @"SOGo Alarms Notifier/1.0" forKey: @"User-Agent"];
|
[headers addObject: @"SOGo Alarms Notifier/1.0" forKey: @"User-Agent"];
|
||||||
[headers addObject: @"high" forKey: @"Importance"];
|
[headers addObject: @"high" forKey: @"Importance"];
|
||||||
[headers addObject: @"1" forKey: @"X-Priority"];
|
[headers addObject: @"1" forKey: @"X-Priority"];
|
||||||
[headers setObject: @"text/plain; charset=\"utf-8\"" forKey: @"Content-Type"];
|
[headers setObject: @"text/html; charset=\"utf-8\"" forKey: @"Content-Type"];
|
||||||
[headers setObject: @"quoted-printable" forKey: @"Content-Transfer-Encoding"];
|
[headers setObject: @"quoted-printable" forKey: @"Content-Transfer-Encoding"];
|
||||||
|
|
||||||
identity = [owner primaryIdentity];
|
identity = [owner primaryIdentity];
|
||||||
fullName = [[identity objectForKey: @"fullName"] asQPSubjectString: @"utf-8"];
|
fullName = [identity objectForKey: @"fullName"];
|
||||||
if ([fullName length])
|
if ([fullName length])
|
||||||
email = [NSString stringWithFormat: @"%@ <%@>", fullName,
|
email = [NSString stringWithFormat: @"%@ <%@>", fullName,
|
||||||
[identity objectForKey: @"email"]];
|
[identity objectForKey: @"email"]];
|
||||||
|
@ -140,20 +151,63 @@
|
||||||
|
|
||||||
- (void) _processAlarm: (iCalAlarm *) alarm
|
- (void) _processAlarm: (iCalAlarm *) alarm
|
||||||
withOwner: (NSString *) ownerId
|
withOwner: (NSString *) ownerId
|
||||||
|
andContainerPath: (NSString *) containerPath
|
||||||
{
|
{
|
||||||
NGMutableHashMap *headers;
|
NGMutableHashMap *headers;
|
||||||
NSArray *attendees;
|
NSArray *attendees, *parts;
|
||||||
NSData *content, *qpContent;
|
NSData *content, *qpContent;
|
||||||
int count, max;
|
int count, max;
|
||||||
SOGoMailer *mailer;
|
SOGoMailer *mailer;
|
||||||
NSString *from;
|
NSString *from, *subject;
|
||||||
SOGoUser *owner;
|
SOGoUser *owner;
|
||||||
|
|
||||||
|
WOContext *localContext;
|
||||||
|
WOApplication *app;
|
||||||
|
SOGoAptMailReminder *p;
|
||||||
|
NSString *pageName;
|
||||||
|
WOResourceManager *rm;
|
||||||
|
|
||||||
|
SOGoAppointmentFolders *folders;
|
||||||
|
SOGoAppointmentFolder *folder;
|
||||||
|
SOGoUserFolder *userFolder;
|
||||||
|
|
||||||
|
|
||||||
owner = [SOGoUser userWithLogin: ownerId];
|
owner = [SOGoUser userWithLogin: ownerId];
|
||||||
mailer = [SOGoMailer mailerWithDomainDefaults: [owner domainDefaults]];
|
mailer = [SOGoMailer mailerWithDomainDefaults: [owner domainDefaults]];
|
||||||
|
|
||||||
headers = [self _headersForAlarm: alarm withOwner: owner];
|
localContext = [WOContext context];
|
||||||
content = [[alarm comment] dataUsingEncoding: NSUTF8StringEncoding];
|
[localContext setActiveUser: owner];
|
||||||
|
app = [[WOApplication alloc] initWithName: @"SOGo"];
|
||||||
|
|
||||||
|
rm = [[WEResourceManager alloc] init];
|
||||||
|
[app setResourceManager:rm];
|
||||||
|
[rm release];
|
||||||
|
[app _setCurrentContext:localContext];
|
||||||
|
|
||||||
|
userFolder = [[localContext activeUser] homeFolderInContext: localContext ];
|
||||||
|
folders = [userFolder privateCalendars: @"Calendar"
|
||||||
|
inContext: localContext];
|
||||||
|
|
||||||
|
pageName = [NSString stringWithFormat: @"SOGoAptMail%@", @"Reminder"];
|
||||||
|
|
||||||
|
p = [app pageWithName: pageName inContext: localContext];
|
||||||
|
|
||||||
|
parts = [containerPath componentsSeparatedByString: @"/"];
|
||||||
|
if ([parts count] > 4)
|
||||||
|
{
|
||||||
|
folder = [folders lookupName: [parts objectAtIndex: 4]
|
||||||
|
inContext: localContext
|
||||||
|
acquire: NO];
|
||||||
|
[p setCalendarName: [folder displayName]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[p setApt: [alarm parent]];
|
||||||
|
[p setAttendees: [[alarm parent] attendees]];
|
||||||
|
|
||||||
|
content = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding];
|
||||||
|
subject = [p getSubject];
|
||||||
|
|
||||||
|
headers = [self _headersForAlarm: alarm withOwner: owner withSubject: subject];
|
||||||
qpContent = [content dataByEncodingQuotedPrintable];
|
qpContent = [content dataByEncodingQuotedPrintable];
|
||||||
from = [[owner primaryIdentity] objectForKey: @"email"];
|
from = [[owner primaryIdentity] objectForKey: @"email"];
|
||||||
|
|
||||||
|
@ -191,6 +245,8 @@
|
||||||
|
|
||||||
int count, max;
|
int count, max;
|
||||||
|
|
||||||
|
[[SOGoProductLoader productLoader] loadAllProducts: YES];
|
||||||
|
|
||||||
if ([[NSUserDefaults standardUserDefaults] stringForKey: @"h"])
|
if ([[NSUserDefaults standardUserDefaults] stringForKey: @"h"])
|
||||||
{
|
{
|
||||||
[self usage];
|
[self usage];
|
||||||
|
@ -209,9 +265,6 @@
|
||||||
[staticAuthenticator retain];
|
[staticAuthenticator retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[SOGoProductLoader productLoader]
|
|
||||||
loadProducts: [NSArray arrayWithObject: @"Appointments.SOGo"]];
|
|
||||||
|
|
||||||
eaMgr = [NSClassFromString (@"SOGoEMailAlarmsManager")
|
eaMgr = [NSClassFromString (@"SOGoEMailAlarmsManager")
|
||||||
sharedEMailAlarmsManager];
|
sharedEMailAlarmsManager];
|
||||||
|
|
||||||
|
@ -225,10 +278,12 @@
|
||||||
second: 0]
|
second: 0]
|
||||||
toDate: toDate
|
toDate: toDate
|
||||||
withMetadata: metadata];
|
withMetadata: metadata];
|
||||||
|
|
||||||
max = [alarms count];
|
max = [alarms count];
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
[self _processAlarm: [alarms objectAtIndex: count]
|
[self _processAlarm: [alarms objectAtIndex: count]
|
||||||
withOwner: [[metadata objectAtIndex: count] objectForKey: @"owner"]];
|
withOwner: [[metadata objectAtIndex: count] objectForKey: @"owner"]
|
||||||
|
andContainerPath: [[[metadata objectAtIndex: count] objectForKey: @"record"] objectForKey: @"c_path"]];
|
||||||
|
|
||||||
// We now update the next alarm date (if any, for recurring
|
// We now update the next alarm date (if any, for recurring
|
||||||
// events or tasks for example). This will also delete any emai
|
// events or tasks for example). This will also delete any emai
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" standalone="yes"?>
|
||||||
|
<!DOCTYPE container>
|
||||||
|
<html
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:var="http://www.skyrix.com/od/binding"
|
||||||
|
xmlns:const="http://www.skyrix.com/od/constant"
|
||||||
|
xmlns:rsrc="OGo:url"
|
||||||
|
xmlns:label="OGo:label">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; font-size: 12px; line-height: 18px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table cellpadding="2" cellspacing="2" border="0" style="width: 100%; max-width: 600px;">
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<td><h1 style="font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc;" class="ng-hide"><var:string
|
||||||
|
value="aptSummary" const:escapeHTML="NO"/></h1></td>
|
||||||
|
</tr>
|
||||||
|
<var:if condition="calendarName.length"
|
||||||
|
><tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="calendar_label" const:escapeHTML="NO"/></th>
|
||||||
|
<td><var:string value="calendarName" const:escapeHTML="NO"/></td>
|
||||||
|
</tr></var:if>
|
||||||
|
<var:if condition="apt.location.length"
|
||||||
|
><tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="location_label" const:escapeHTML="NO"/></th>
|
||||||
|
<td><var:string value="apt.location" const:escapeHTML="NO"/></td>
|
||||||
|
</tr></var:if>
|
||||||
|
<tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="startDate_label" const:escapeHTML="NO"/></th>
|
||||||
|
<td><var:string value="aptStartDate" const:escapeHTML="NO"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="endDate_label" const:escapeHTML="NO"/></th>
|
||||||
|
<td><var:string value="aptEndDate" const:escapeHTML="NO"/></td>
|
||||||
|
</tr>
|
||||||
|
<var:if condition="apt.comment.length"
|
||||||
|
><tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="comment_label" const:escapeHTML="NO"/></th>
|
||||||
|
<td><var:string value="apt.comment" const:escapeHTML="NO"/></td>
|
||||||
|
</tr>
|
||||||
|
</var:if>
|
||||||
|
|
||||||
|
<var:if condition="attendees.count"
|
||||||
|
><tr></tr><tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="organizer_label" const:escapeHTML="NO"/></th>
|
||||||
|
<var:if condition="organizer.cn">
|
||||||
|
<td><a var:href="organizer.email"><var:string value="organizer.cn" const:escapeHTML="NO"/></a></td>
|
||||||
|
</var:if>
|
||||||
|
<var:if condition="organizer.cn" const:negate="YES">
|
||||||
|
<td><a var:href="organizer.email"><var:string value="organizer.rfc822Email" const:escapeHTML="NO"/></a></td>
|
||||||
|
</var:if>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th align="right" style="font-weight: bold;"><var:string label:value="attendee_label" const:escapeHTML="NO"/></th>
|
||||||
|
<var:foreach list="attendees" item="currentRecipient">
|
||||||
|
<var:if condition="currentRecipient.cn">
|
||||||
|
<td><a var:href="currentRecipient.email"><var:string value="currentRecipient.cn" const:escapeHTML="NO"/></a></td>
|
||||||
|
</var:if>
|
||||||
|
<var:if condition="currentRecipient.cn" const:negate="YES">
|
||||||
|
<td><a var:href="currentRecipient.email"><var:string value="currentRecipient.rfc822Email" const:escapeHTML="NO"/></a></td>
|
||||||
|
</var:if>
|
||||||
|
<tr></tr><th align="right"></th>
|
||||||
|
</var:foreach>
|
||||||
|
</tr>
|
||||||
|
</var:if>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue