{"id":447,"date":"2005-12-23T15:33:07","date_gmt":"2005-12-23T13:33:07","guid":{"rendered":"http:\/\/frenchfragfactory.net\/ozh\/my-projects\/wordpress-theme-zip\/"},"modified":"2007-05-09T23:55:32","modified_gmt":"2007-05-09T21:55:32","slug":"wordpress-theme-zip","status":"publish","type":"page","link":"https:\/\/planetozh.com\/blog\/my-projects\/wordpress-theme-zip\/","title":{"rendered":"WordPress Theme Zip"},"content":{"rendered":"<p>When working on a WordPress Theme, I find one thing very tedious : repacking the theme.zip archive, making sure all paths within the zip file are correct, then upload and replace the archive. Doing this every time I make the slightest modification to a file (&quot;doh ? typo in a .css ?&quot;) was too unbearable not to come up with a smart and lazy way to manage this task :)<\/p>\n<h2>The 3 line explanation (aka &quot;WTF?&quot;)<\/h2>\n<ul>\n<li>I have a theme directory : <em>ozh\/wp-content\/themes\/fake-theme<\/em><\/li>\n<li>I&#39;m too lazy to maintain, update, upload a zip file of the theme each time I modify the .css or anything else.<\/li>\n<li>One PHP script creates the zip file ready for download : <a href=\"http:\/\/planetozh.com\/download\/themes\/fake-theme.zip.php\">fake-theme.zip<\/a>&#8230;<\/li>\n<li>&#8230; or displays a list of the <a href=\"http:\/\/planetozh.com\/download\/themes\/fake-theme.zip.php?list=1\">theme files<\/a><\/li>\n<\/ul>\n<p>Ok, I lied, that&#39;s 4 lines.<\/p>\n<h2>WordPress Theme Zip creates zip files for you<\/h2>\n<p>The script generates on the fly a zip archive from an actual WordPress theme on your blog. Upload your theme, and no longer mind about updating your <em>theme.zip<\/em> if you ever happen to modify something in it.<\/p>\n<p>For example, I&#39;ve created a (broken and fake) theme, named <em>Faked Theme<\/em>, which actually sits into my <em>wp-content\/themes<\/em> directory. It&#39;s populated with various useless files in nonsense subdirectories for a demo purpose.<\/p>\n<div id=\"ig-sh-1\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">code<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"code\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u0153\u00e2\u201d\u20ac\u00e2\u201d\u20ac\u00e2\u201d\u20acfake-theme<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; fake-archive.txt.zip<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; fake.js<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; porn.php<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; random.php<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; readme.txt<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; sample.css<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u0153\u00e2\u201d\u20ac\u00e2\u201d\u20ac\u00e2\u201d\u20acimages<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; &nbsp; &nbsp; addpluck.png<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a &nbsp; &nbsp; &nbsp; xml.gif<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201a<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; \u00e2\u201d\u201d\u00e2\u201d\u20ac\u00e2\u201d\u20ac\u00e2\u201d\u20acvery<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; &nbsp; &nbsp; \u00e2\u201d\u201d\u00e2\u201d\u20ac\u00e2\u201d\u20ac\u00e2\u201d\u20acdeep<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u00e2\u201d\u201d\u00e2\u201d\u20ac\u00e2\u201d\u20ac\u00e2\u201d\u20acsubdir<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\u00e2\u201d\u201a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deep.txt<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>Now that I explained why I&#39;m too lazy to pack it as a ready-for-use zip file, I&#39;m just linking to a copy of the WordPress Theme Zip script : <a href=\"http:\/\/planetozh.com\/download\/themes\/fake-theme.zip.php\">fake-theme.zip<\/a>.<\/p>\n<p>You&#39;ll notice that a suffix is automatically appended to the zip filename, here with date format &quot;yyyymmdd&quot;. It&#39;s a customizable option that allows easy file update tracking.<\/p>\n<p>Another customizable feature is that the script can list files the zip contains, so that users don&#39;t need to download anything if they just want to see what&#39;s inside, or what file has changed since they downloaded it : <a href=\"http:\/\/planetozh.com\/download\/themes\/fake-theme.zip.php?list=1\">list fake-theme.zip content<\/a>.<\/p>\n<p>I made things so that the listing is more or less as usable as your destkop WinZip or similar software : you can sort columns by clicking on headers, and you can view files from within the archive by clicking on their filenames. Text files (php, htm, txt, js and css by default) and images (gif, jpg and png) are shown right into the browser, any other extension is not displayed.<\/p>\n<p>(A note about column sorting : while it seems to be working fine with numbers, it sometimes sorts strings a bit weirdly. Ho well, it&#39;s just here to make things prettier, but it&#39;s not *that* useful anyway :)<\/p>\n<h2>Download WordPress Theme Zip<\/h2>\n<p>Get the script while it&#39;s hot :<\/p>\n<ul>\n<li><a href=\"http:\/\/planetozh.com\/download\/wordpress-theme-zip.txt\">wordpress-theme-zip.txt<\/a> (download and save as .php)<\/li>\n<li><a href=\"http:\/\/planetozh.com\/download\/wordpress-theme-zip.php\">wordpress-theme-zip.php<\/a> (highlighted code, copy and paste in a blank file, but do not download as is)<\/li>\n<\/ul>\n<p>The script uses <a href=\"http:\/\/smiledsoft.com\/\">Smiled Soft<\/a>&#39;s <a href=\"http:\/\/smiledsoft.com\/demos\/phpzip\/buy.shtml\">phpZIP<\/a> (the free version), a PHP class to create zip files. Download <a href=\"http:\/\/smiledsoft.com\/demos\/phpzip\/buy.shtml\">phpZIP<\/a> and put it anywhere on your web server (it&#39;s actually one 9kb file named <em>ss_zip.class.php<\/em>)<\/p>\n<h2>Configure and use<\/h2>\n<p>You used to have something like <em>yourtheme.zip<\/em> in a download directory. Delete your regular zip archive, replace it with a copy of the WordPress Theme Zip script and give it a name that will make the user think it is a regular archive : yourtheme.zip.php for example (remember, it&#39;s still a PHP script, don&#39;t forget the PHP extension)<\/p>\n<p>Now configure a very few options at the beginning of the script :<\/p>\n<p><strong>$ziptheme[&#39;theme_name&#39;]<\/strong><br \/>\nThis is the name of the theme directory you want to zip. This must be a real directory name from your <em>wp-content\/themes\/<\/em> directory, such as &quot;classic&quot; or &quot;default&quot;.<\/p>\n<p><strong>$ziptheme[&#39;theme_page&#39;]<\/strong><br \/>\nPut here a page URL that will be displayed in the footer of the archive file list, so that users that would land directly on the list from a search engine or any other referral would be able to find their way to your theme page or to your blog.<\/p>\n<p>These two options are the mandatory options you need to edit every time you will make a copy of the script (one copy for each theme you want to make available for download)<\/p>\n<p>The next options are more general stuff you won&#39;t change too often, if more than once.<\/p>\n<p><strong>$ziptheme[&#39;datesuffix&#39;]<\/strong><br \/>\nThis string is a suffix that is automatically appended to generated zip files, and uses PHP&#39;s <a href=\"http:\/\/php.net\/date\">date()<\/a> syntax.<br \/>\nFor example, with $ziptheme[&#39;theme_name&#39;] = &#39;classic&#39;, <\/p>\n<ul>\n<li>$ziptheme[&#39;datesuffix&#39;] = &quot; &rarr; classic.zip<\/li>\n<li>$ziptheme[&#39;datesuffix&#39;] = &#39;Ymd&#39; &rarr; classic-20051224.zip<\/li>\n<li>$ziptheme[&#39;datesuffix&#39;] = &#39;Y-m-d-H-i-s&#39; &rarr; classic-2005-12-22-03-34-55.zip<\/li>\n<li>$ziptheme[&#39;datesuffix&#39;] = &#39;\\a\\l\\p\\h\\aY&#39; &rarr; classic-alpha2005.zip<\/li>\n<\/ul>\n<p><strong>$ziptheme[&#39;path_to_zipclass&#39;]<\/strong><br \/>\nPut here the physical path to phpZIP class file, e.g. <em>\/home\/you\/lib\/zipfile\/ss_zip.class.php<\/em><\/p>\n<p><strong>$ziptheme[&#39;rootdir&#39;]<\/strong><br \/>\nThis is the physical path &mdash; not URL &mdash; of your Themes directory, e.g. <em>\/home\/you\/wordpress\/wp-content\/themes<\/em>. No trailing slash please.<\/p>\n<p><strong>$ziptheme[&#39;rooturl&#39;]<\/strong><br \/>\nThis is the URL of your blog, something like <em>http:\/\/yourblog.com\/wordpress<\/em>. No trailing slash please.<\/p>\n<p><strong>$ziptheme[&#39;enable_report&#39;]<\/strong><br \/>\nIf for some reason you don&#39;t want people to be able to list files by adding <em>?list=1<\/em> to your archive, set this variable to 0 (zero). Leave to 1 (one) otherwise.<\/p>\n<p><strong>$ziptheme[&#39;enable_file_preview&#39;]<\/strong><br \/>\nSimilarly, set this one to 0 (zero) to disable file preview. This option needs <strong>$ziptheme[&#39;enable_report&#39;]<\/strong><br \/>\n to be set, of course.<\/p>\n<p><strong>$ziptheme[&#39;textfiles&#39;]<\/strong> and <strong>$ziptheme[&#39;imagefiles&#39;]<\/strong><br \/>\nEach of these two options contains an array of common file extension that can be printed in a browser window, i.e. <em>txt, php, htm, html, css, js, xml<\/em> for text files, and <em>gif, png, jpg<\/em> for images.<br \/>\nYou shouldn&#39;t really have to modify this, but the option is here just in case.<\/p>\n<p><strong>CSS style<\/strong><br \/>\nWhile this is not a option as such, you can easily customize the CSS presentation of listings and file viewing. You simply need to edit the very last function of the script, which outputs the CSS declaration.<\/p>\n<h2>A word about security<\/h2>\n<p>I&#39;m rather confident that my script is absolutely secure regarding access to arbitrary files, and enabling the file list feature or file preview won&#39;t compromise your web host security. You cannot see any file outside your theme directory with tricks like <em>?view=..\/..\/..\/etc\/password<\/em> and such. Since you &quot;hardcode&quot; the directory path in the script itself and do not pass it as an argument, things will be fine.<\/p>\n<p>And if you are of the parano\u00c3\u00afd kind, you can still disable the file listing and viewing options.<\/p>\n<h2>Feedback<\/h2>\n<p>Positive feedback, praise trackbacks, love letters and clicking sprees on my PayPal &quot;Donate&quot; button are strongly encouraged, as usual. But if you just have  a question or want to report a bug, well, that&#39;s possible too :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working on a WordPress Theme, I find one thing very tedious : repacking the theme.zip archive, making sure all paths within the zip file are correct, then upload and replace the archive. Doing this every time I make the slightest modification to a file (&quot;doh ? typo in a .css ?&quot;) was too unbearable [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":241,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-447","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":0,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/447\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/241"}],"wp:attachment":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/media?parent=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}