magic fields in wordpress

Custom fields in wordpress is a surprise, with custom post type wordpress suddenly become the first choice for out-of-box CMS system.

There are many plugin around, the most of them require some medium level PHP skill to change template or theme.

Some cool plugins like Custom Post type UI, just custom post type and advanced custom type. But those plugin still have one problem to solve, how to make the input UI easier to use. One common problem is in the input screen, custom field displayed twice, and still give user flexibility to add other custom fields.

Custom field template suppose fix it, but it seems still need PHP code change somewhere.

Magic fields 2 solved this problem eventual, by introducing some style middle tables at backend, the admin UI looks much cleaner. And data storage is still in post_metadata.





Change git external submodule to local repo

Why doing this? an external submodule is not public anymore.

rm .gitmodules, or edit it to remove the selected submodule.

Remove the submodule’s entry in the .git/config

git rm –cached external/selected-submodule

git add external/selected-submodule

git commit -m

git push


How to calculate ‘Tomorrow at 4 pm’ in iOS

NSCalendar *calendar = [NSCalendar gregorianCalendar];
NSDateComponents *oneDayComponents = [[NSDateComponents alloc] init]; = 1;
NSDate *tomorrow = [calendar dateByAddingComponents:oneDayComponents toDate:[NSDate date] options:nil];
NSUInteger unitFlags = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *tomorrowAt4PM = [calendar components:unitFlags fromDate:tomorrow];
tomorrowAt4PM.hour = 16;
tomorrowAt4PM.minute = 0;
tomorrowAt4PM.second = 0;
NSDate *alarmDate = [calendar dateFromComponents:tomorrowAt4PM];

Facebook sharing feature in iOS app

Classic/Obsolete(?) way

Install SDK

Drag framework folder into XCode project.

Drag bundle into XCode project.

Drag deprecated header folder into XCode project. check copy in needed.

When picking dependency libraries, set them to optional, to allow app running on iOS5.

Set other link flag to -lsqlite3.0

Those steps are fully documented on facebook developer site:

Note: we are using old fashion Facebook sharing feature in app.  (FBDelegate vs. FBRequest) Because my client doesn’t like posting story on their wall without a preview. This way app will popup a separated window to display link to share, image, title, description, etc. User needs to type something in the textbox with placeholder ‘say something about this…’

Note: again, preset message feature has been disabled by Facebook as of 2012.

In app, we are adding #include “Facebook.h” to implement this.

Note: you can use sharekit library for this, but I want to figure out what’s happening behind the scene.

In the place you want to popup Facebook share options to user, do this to open a Facebook session.

// openSessionWithAllowLoginUI will be called by the actual sharing screen where users can click button to post message on their wall.
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
    NSArray *permission = [[NSArray alloc] initWithObjects:@"user_likes",@"publish_actions", nil];

    return [FBSession openActiveSessionWithPublishPermissions:permission
                                            completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
                                                [self sessionStateChanged:session state:status error:error];

NSString *const FBSessionStateChangedNotification = @"com.bitrixsoft.Login:FBSessionStateChangedNotifiction";

- (void)sessionStateChanged:(FBSession *)session
                    state:(FBSessionState) state
                    error:(NSError *)error
    switch (state) {
        case FBSessionStateOpen:
            if (!error) {
                NSLog(@"User session found");
        case FBSessionStateClosed:
        case FBSessionStateClosedLoginFailed:
            [FBSession.activeSession closeAndClearTokenInformation];

    [[NSNotificationCenter defaultCenter]

    if (error) {
        [[[UIAlertView alloc]
          otherButtonTitles:nil] show];

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    return [FBSession.activeSession handleOpenURL:url];

I put this in appDelegate, so it can be shared. I don’t want to call this in appDelegate, otherwise the redirect to facebook to ask permission/login will annoy users.

Add those in appDelegate.h file

extern NSString *const FBSessionStateChangedNotification;

- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI;

Before calling opensession, sharing window should subscribe statechange notification.

[[NSNotificationCenter defaultCenter]

- (void)sessionStateChanged:(NSNotification *)notification
    if ((FBSession.activeSession.isOpen)) {

        if (nil == self.facebook) {
            self.facebook = [[Facebook alloc]

            self.facebook.accessToken = FBSession.activeSession.accessToken;
            self.facebook.expirationDate = FBSession.activeSession.expirationDate;

            // resume sharing routine here, because first time attempt without login will stop after app back from background, 
            // but this method will get statechange notifcation, so perfect to resume/restart here.
            [self shareViaFacebook];

        self.facebook = nil;

Finally, the actual post action:

- (IBAction)shareOptions:(id)sender

    BNAppDelegate * appDelegate = (BNAppDelegate*)[[UIApplication sharedApplication] delegate];
    [appDelegate openSessionWithAllowLoginUI:YES];

    UIActionSheet * options = [[UIActionSheet alloc]
                               otherButtonTitles:@"Twitter", @"Facebook", @"email", nil];

    [options showInView:self.view];
- (void)shareViaFacebook
    NSString * message = @"test msg from my test ios app";

    // no nil allow in any parameter
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"Bitrix News iPhone app", @"name",
                                   _post.title, @"caption",
                                   _post.exerpt, @"description",
                                   @"", @"link",
                                   @"", @"picture",
                                   message, @"message", //already obsolete, don't bother, facebook will ignore it anyway

    [self.facebook dialog:@"feed" andParams:params andDelegate:self];


Someother gotcha, app identifier must match between app and setting in, otherwise facebook will complain app is misconfigured when starting the session.