Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

refinements

  • Loading branch information...
commit 2a78361db3998a5ce4d2d83b9a143eace7ce4074 1 parent 7c1c50d
Ben Balter authored August 18, 2012
BIN  includes/.DS_Store
Binary file not shown
0  markdownify/LICENSE_LGPL.txt → includes/markdownify/LICENSE_LGPL.txt
File renamed without changes
0  markdownify/TODO → includes/markdownify/TODO
File renamed without changes
0  markdownify/example.php → includes/markdownify/example.php
File renamed without changes
0  markdownify/markdownify.php → includes/markdownify/markdownify.php
File renamed without changes
0  markdownify/markdownify_cli.php → includes/markdownify/markdownify_cli.php
File renamed without changes
0  markdownify/markdownify_extra.php → includes/markdownify/markdownify_extra.php
File renamed without changes
0  markdownify/parsehtml/parsehtml.php → includes/markdownify/parsehtml/parsehtml.php
File renamed without changes
0  spyc.php → includes/spyc.php
File renamed without changes
282  jekyll-export.php
... ...
@@ -1,17 +1,16 @@
1 1
 <?php
2 2
 /*
3  
-Plugin Name: Name Of The Plugin
4  
-Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
5  
-Description: A brief description of the Plugin.
6  
-Version: The Plugin's Version Number, e.g.: 1.0
7  
-Author: Name Of The Plugin Author
8  
-Author URI: http://URI_Of_The_Plugin_Author
9  
-License: A "Slug" license name e.g. GPL2
  3
+Plugin Name: WordPress to Jekyll Exporter
  4
+Description: Exports WordPress posts, pages, and options as YAML files parsable by Jekyll
  5
+Version: 1.0
  6
+Author: Benjamin J. Balter
  7
+Author URI: http://ben.balter.com
  8
+License: GPLv3 or Later
10 9
 
11  
-Copyright YEAR  PLUGIN_AUTHOR_NAME  (email : PLUGIN AUTHOR EMAIL)
  10
+Copyright 2012  Benjamin J. Balter  (email : Ben@Balter.com)
12 11
 
13 12
 This program is free software; you can redistribute it and/or modify
14  
-it under the terms of the GNU General Public License, version 2, as 
  13
+it under the terms of the GNU General Public License, version 2, as
15 14
 published by the Free Software Foundation.
16 15
 
17 16
 This program is distributed in the hope that it will be useful,
@@ -26,130 +25,220 @@
26 25
 
27 26
 class Jekyll_Export {
28 27
 
29  
-	private $zip_folder = 'jekyll-export/';
30  
-	
  28
+	private $zip_folder = 'jekyll-export/'; //folder zip file extracts to
  29
+	public $rename_options = array( 'site', 'blog' ); //strings to strip from option keys on export
  30
+
  31
+	/**
  32
+	 * Hook into WP Core
  33
+	 */
31 34
 	function __construct() {
32  
-		
33  
-		if ( !class_exists( 'spyc' ) )
34  
-			require_once( dirname( __FILE__ ) . '/spyc.php' );
35  
-			
36  
-		if ( !class_exists( 'Markdownify' ) )
37  
-			require_once( dirname( __FILE__ ) . '/markdownify/markdownify.php' );
38  
-		
39  
-		$this->dir = sys_get_temp_dir() . '/wp-jekyll-' . md5( time() ) . '/';
40  
-		$this->zip = sys_get_temp_dir() . '/wp-jekyll.zip';
41  
-		mkdir( $this->dir );
42  
-		mkdir( $this->dir . '_posts/' );
43  
-		
  35
+
  36
+		add_action( 'admin_menu', array( &$this, 'register_menu' ) );
  37
+		add_action( 'current_screen', array( &$this, 'callback' ) );
  38
+
44 39
 	}
45  
-	
  40
+
  41
+
  42
+	/**
  43
+	 * Listens for page callback, intercepts and runs export
  44
+	 */
  45
+	function callback() {
  46
+
  47
+		if ( get_current_screen()->id != 'jekyll-export' )
  48
+			return;
  49
+
  50
+		if ( !current_user_can( 'manage_options' ) )
  51
+			return;
  52
+
  53
+		$this->export();
  54
+		exit();
  55
+
  56
+	}
  57
+
  58
+
  59
+	/**
  60
+	 * Add menu option to tools list
  61
+	 */
  62
+	function register_menu() {
  63
+
  64
+		add_submenu_page( 'tools.php', __( 'Export to Jekyll', 'jekyll-export' ), __( 'Export to Jekyll', 'jekyll-export' ), 'manage_options', 'jekyll-export', null );
  65
+
  66
+	}
  67
+
  68
+
  69
+	/**
  70
+	 * Get an array of all post and page IDs
  71
+	 * Note: We don't use core's get_posts as it doesn't scale as well on large sites
  72
+	 */
46 73
 	function get_posts() {
47  
-		
  74
+
48 75
 		global $wpdb;
49 76
 		return $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_status IN ( 'publish', 'draft' ) AND post_type IN ('post', 'page' )" );
50  
-		
  77
+
51 78
 	}
52  
-	
  79
+
  80
+
  81
+	/**
  82
+	 * Convert a posts meta data (both post_meta and the fields in wp_posts) to key value pairs for export
  83
+	 */
53 84
 	function convert_meta( $post ) {
54  
-		
55  
-		foreach( $post as $key => $value ) {
56  
-		
  85
+
  86
+		//convert non-content columns in wp_posts table
  87
+		foreach ( $post as $key => $value ) {
  88
+
57 89
 			if ( $key == 'post_content' )
58 90
 				continue;
59  
-							
  91
+
  92
+			//strip post_ from the key, as it will be page.foo in jekyll
60 93
 			$key = str_replace( 'post_', '', $key );
61 94
 			$output[ strtolower( $key)  ] = $value;
62  
-			
  95
+
63 96
 		}
64  
-		
  97
+
  98
+		//convert traditional post_meta values, hide hidden values
65 99
 		foreach ( get_post_custom( $post ) as $key => $value ) {
66  
-			
  100
+
67 101
 			if ( substr( $key, 0, 1 ) == '_' )
68 102
 				continue;
69  
-		
  103
+
70 104
 			$output[ $key ] = $value;
71  
-			
  105
+
72 106
 		}
73  
-		
  107
+
74 108
 		return $output;
75  
-		
  109
+
76 110
 	}
77  
-	
  111
+
  112
+
  113
+	/**
  114
+	 * Convert post taxonomies for export
  115
+	 */
78 116
 	function convert_terms( $post ) {
79 117
 
80 118
 		$output = array();
81  
-		foreach( get_taxonomies( array( 'object_type' => array( get_post_type( $post ) ) ) ) as $tax ) { 
  119
+		foreach ( get_taxonomies( array( 'object_type' => array( get_post_type( $post ) ) ) ) as $tax ) {
82 120
 			$terms = wp_get_post_terms( $post, $tax );
83 121
 			$output[ $tax ] = wp_list_pluck( $terms, 'name' );
84 122
 		}
85  
-		
  123
+
86 124
 		return $output;
87  
-		
  125
+
88 126
 	}
89  
-	
90  
-	function convert() {
91 127
 
92  
-		$this->convert_options();
93  
-		
  128
+
  129
+	/**
  130
+	 * Loop through and convert all posts to MD files with YAML headers
  131
+	 */
  132
+	function convert_posts() {
  133
+
94 134
 		foreach ( $this->get_posts() as $postID ) {
95  
-			$md = new Markdownify;
  135
+			$md = new Markdownify_Extra();
96 136
 			$post = get_post( $postID );
97  
-			$meta = $this->convert_meta( $post );
98  
-			$meta = array_merge( $meta, $this->convert_terms( $postID ) );
  137
+			$meta = array_merge( $this->convert_meta( $post ), $this->convert_terms( $postID ) );
99 138
 			$output = Spyc::YAMLDump($meta);
100  
-			$output .= "\n---\n";
  139
+			$output .= "---\n";
101 140
 			$output .= $md->parseString( apply_filters( 'the_content', $post->post_content ) );
102 141
 			$this->write( $output, $post );
103 142
 		}
104  
-		
  143
+
  144
+	}
  145
+
  146
+
  147
+	/**
  148
+	 * Main function, bootstraps, converts, and cleans up
  149
+	 */
  150
+	function export() {
  151
+
  152
+		if ( !class_exists( 'spyc' ) )
  153
+			require_once dirname( __FILE__ ) . '/includes/spyc.php';
  154
+
  155
+		if ( !function_exists( 'Markdown' ) )
  156
+			require_once dirname( __FILE__ ) . '/includes/markdownify/markdownify_extra.php';
  157
+
  158
+		$this->dir = sys_get_temp_dir() . '/wp-jekyll-' . md5( time() ) . '/';
  159
+		$this->zip = sys_get_temp_dir() . '/wp-jekyll.zip';
  160
+		mkdir( $this->dir );
  161
+		mkdir( $this->dir . '_posts/' );
  162
+
  163
+		$this->convert_options();
  164
+		$this->convert_posts();
105 165
 		$this->zip();
106 166
 		$this->send();
107  
-		
  167
+		$this->cleanup();
  168
+
108 169
 	}
109  
-	
  170
+
  171
+
  172
+	/**
  173
+	 * Convert options table to _config.yml file
  174
+	 */
110 175
 	function convert_options() {
111  
-		
  176
+
112 177
 		$options = wp_load_alloptions();
113 178
 		foreach ( $options as $key => &$option ) {
114 179
 
115 180
 			if ( substr( $key, 0, 1 ) == '_' )
116 181
 				unset( $options[$key] );
117  
-		
  182
+
  183
+			//strip site and blog from key names, since it will become site. when in Jekyll
  184
+			foreach ( $this->rename_options as $rename ) {
  185
+
  186
+				$len = strlen( $rename );
  187
+				if ( substr( $key, 0, $len ) != $rename )
  188
+					continue;
  189
+
  190
+				$this->rename_key( $options, $key, substr( $key, $len ) );
  191
+
  192
+			}
  193
+
118 194
 			$option = maybe_unserialize( $option );
119 195
 
120 196
 		}
121  
-		
  197
+
122 198
 		$output = Spyc::YAMLDump( $options );
123  
-		$output .= '---';
124  
-		
125  
-		file_put_contents( $this->dir . '_config.yml', $output );
126 199
 
  200
+		//strip starting "---"
  201
+		$output = substr( $output, 4 );
  202
+
  203
+		file_put_contents( $this->dir . '_config.yml', $output );
127 204
 
128 205
 	}
129  
-	
  206
+
  207
+
  208
+	/**
  209
+	 * Write file to temp dir
  210
+	 */
130 211
 	function write( $output, $post ) {
131  
-		
  212
+
132 213
 		$filename = ( get_post_type( $post ) == 'post' ) ? date( 'Y-m-d' ) . '-' . $post->post_name . '.md': $post->post_name . '.md';
133 214
 		$prefix = ( get_post_type( $post ) == 'post' ) ? '_posts/' : '';
134 215
 		file_put_contents( $this->dir . $prefix . $filename, $output );
135  
-		
  216
+
136 217
 	}
137  
-	
  218
+
  219
+
  220
+	/**
  221
+	 * Zip temp dir
  222
+	 */
138 223
 	function zip() {
139  
-		
  224
+
140 225
 		//create zip
141 226
 		$zip = new ZipArchive();
142 227
 		$zip->open( $this->zip, ZIPARCHIVE::CREATE );
143  
-		
  228
+
144 229
 		$this->_zip( $this->dir . '_config.yml', $zip );
145 230
 		$this->_zip( $this->dir . '*.md', $zip );
146  
-		$this->_zip( $this->dir . '_posts/*.md', $zip );			
  231
+		$this->_zip( $this->dir . '_posts/*.md', $zip );
147 232
 		$zip->close();
148  
-		
  233
+
149 234
 	}
150  
-	
  235
+
  236
+
  237
+	/**
  238
+	 * Helper function to add a file to the zip
  239
+	 */
151 240
 	function _zip( $q, &$zip ) {
152  
-		
  241
+
153 242
 		//loop through all files in directory
154 243
 		foreach ( glob( $q ) as $path ) {
155 244
 
@@ -158,35 +247,66 @@ function _zip( $q, &$zip ) {
158 247
 
159 248
 			//add file
160 249
 			$zip->addFile( realpath( $path ), $local_path );
161  
-		
  250
+
162 251
 		}
163  
-		
  252
+
164 253
 	}
165  
-	
  254
+
  255
+
  256
+	/**
  257
+	 * Send headers and zip file to user
  258
+	 */
166 259
 	function send() {
167  
-		
  260
+
168 261
 		//send headers
169 262
 		header( 'Content-Type: application/zip' );
170 263
 		header( "Content-Disposition: attachment; filename=jekyll-export.zip" );
171 264
 		header( 'Content-Length: ' . filesize( $this->zip ) );
172  
-		
  265
+
173 266
 		//read file
174 267
 		readfile( $this->zip );
175  
-		    	
  268
+
176 269
 	}
177  
-	
178  
-	function __destruct( ) {
  270
+
  271
+
  272
+	/**
  273
+	 * Clear temp files
  274
+	 */
  275
+	function cleanup( ) {
  276
+
  277
+		foreach ( glob( $this->dir . '_posts/*' ) as $file )
  278
+			unlink( $file );
179 279
 
180 280
 		foreach ( glob( $this->dir . '*' ) as $file )
181 281
 			unlink( $file );
182  
-		
  282
+
  283
+		rmdir( $this->dir . '_posts/' );
183 284
 		rmdir( $this->dir );
  285
+
184 286
 		unlink( $this->zip );
185 287
 
186 288
 	}
187 289
 
188  
-	
  290
+
  291
+	/**
  292
+	 * Rename an assoc. array's key without changing the order
  293
+	 */
  294
+	function rename_key( &$array, $from, $to ) {
  295
+
  296
+		$keys = array_keys( $array );
  297
+		$index = array_search( $from, $keys );
  298
+
  299
+		if ( $index === false )
  300
+			return;
  301
+
  302
+		$keys[ $index ] = $to;
  303
+		$array = array_combine( $keys, $array );
  304
+
  305
+
  306
+	}
  307
+
  308
+
189 309
 }
190 310
 
191  
-$je = new Jekyll_Export();
192  
-$je->convert();
  311
+
  312
+$je = new Jekyll_Export();

0 notes on commit 2a78361

Please sign in to comment.
Something went wrong with that request. Please try again.