Export extra files for a plugin
One of the most common requests for a plugin is to be able to export additional files for a particular page. There are quite a few snippets of code scattered around the forums but they can be quite cryptic for new plugin developers; this page attempts to try to shed some light on what this feature does (and doesn't) do.
The method called in the plugin to generate the extra pages is
- (NSArray *)extraFilesNeededInExportFolder:(NSDictionary *)params
Every item returned by this method will be written to the "files" folder for a page. This location isn't changeable, nor can you export into sub-folders. Every plugin developer basically has to deal with this restriction for the moment.
Each item in the array describes an individual output file. The value of the item can either be an NSString (containing the path to the file you want copied) or an NSDictionary (describing an HTML page you want RapidWeaver to generate).
Bundle Files
To export a file from the "Resources" folder of the plugin bundle, you simply add the path of the file in the bundle to the extra file array. The following example will export a Flash file called "myflash.swf" from the bundle resources.
- (NSArray *)extraFilesNeededInExportFolder:(NSDictionary *)params
{
NSMutableArray *extraFiles;
NSString *flashFile;
NSBundle *localBundle;
// Create our extra file array
extraFiles = [NSMutableArray array];
// Pick up a reference to our plugin bundle
localBundle = [NSBundle bundleForClass:[self class]];
// Get the absolute path of the flash file in the plugin bundle
flashFile = [localBundle pathForResource:@"myflash" ofType:@"swf"];
// Add the file to our extra file array
[extraFiles addObject:flashFile];
return extraFiles;
}
The following simple example exports two png files when publishing. The pngs should be located in the plugin bundle.
- (NSArray *)extraFilesNeededInExportFolder:(NSDictionary*)params
{
// Set up a reference to our plugin bundle
NSString* resources = [pluginBundle resourcePath];
// Add the files to an array and return the results
return [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@/%@",resources,@"rss.gif"],
[NSString stringWithFormat:@"%@/%@",resources,@"smiley_smile.png"],
[NSString stringWithFormat:@"%@/%@",resources,@"smiley_wink.png"],
nil];
}
Temporary Files
RapidWeaver provides a temporary file location for a plugin to use when generating the output for pages. For example, if you want to output an HTML file without any extra processing from RapidWeaver, you can write it to the temporary folder, point RapidWeaver at it and export it from there.
- (NSString*)tempFilesDirectory
{
return [self tempFilesDirectory:@"RWExamplePlugin"];
}
- (NSArray *)extraFilesNeededInExportFolder:(NSDictionary*)params
{
NSMutableArray *extraFiles;
NSMutableString *pageContent;
NSString *pagePath;
// Create our extra file array
extraFiles = [NSMutableArray array];
// Generate our page content in a mutable string
pageContent = [NSMutableString string];
[pageContent appendString:@"<b>Hello World!</b>"];
// Construct a path for the file in the temporary folder
pagePath = [self tempFilesDirectory] stringByAppendingPathComponent:@"mypage.html"];
// Write the new page!
[pageContent writeToFile:pagePath atomically:NO encoding:NSUTF8StringEncoding error:nil];
// Add the file to our extra file array
[extraFiles addObject:pagePath];
return extraFiles;
}
Note that this example has a utility method for providing a temporary folder for the plugin for this page. This example also explicitly adds the path for the file in the temporary folder to the extra files array. In other examples, you'll often see a line at the end of -extraFilesNeededInExportFolder: that looks like this
[extraFiles arrayByAddingObjectsFromArray:[self directoryContents:[self tempFilesDirectory]]];
This is a slightly different way to add files in the temporary folder to the extra files array. All this line of code is does is build an array of all the files that are in the temporary folder for the plugin. Then it adds that array to the extraFiles array.
If you have this line at the bottom of your -extraFilesNeededInExportFolder: then you don't need to explicitly add files in the temporary folder to the extra files array. Which method you choose depends on how many temporary files you generate and whether you want to explicitly add them or not.
External Files
If you want to output a file that isn't in either the bundle or temporary folder (e.g. an image file in a users' Pictures folder) then you simply follow the examples above and add the absolute pathname to the extraFiles array. Care must be taken when building plugins that use this technique though; if a user deletes the external file after the page has been published, the image will be missing when you republish the page.
Content Pages
If you want to generate additional HTML pages using the same theme as the main HTML content page, then you can use the -contentOnlySubpageWithHTML:name: method
- (NSArray *)extraFilesNeededInExportFolder:(NSDictionary*)params
{
NSString *pageContent;
NSMutableArray *extraFiles;
NSMutableDictionary *pageObject;
// Create our extraFile array
extraFiles = [NSMutableArray array];
// Create a string with the content that we want to output in a styled page
pageContent = [NSString stringWithString:@"<b>Hello World!</b>"];
// Create our new page!
pageObject = [self contentOnlySubpageWithHTML:pageContent name:@"myPage.html"];
// Add the page dictionary to our extra file array
[extraFiles addObject:pageObject];
return extraFiles;
}
You can see the subtle difference from previous examples. In this case, the -contentOnlySubpageWithHTML:name: method creates an NSMutableDictionary that we add to the extraFiles array. This dictionary describes the page that we want RapidWeaver to generate. When we call -contentOnlySubpageWithHTML:name: we always specify the name of the file that we want to generate.
You can, of course, mix all of these techniques in the same -extraFilesNeededInExportFolder: method.
