{"id":1097,"date":"2017-04-26T20:55:31","date_gmt":"2017-04-27T01:55:31","guid":{"rendered":"http:\/\/blog.ls-al.com\/?p=1097"},"modified":"2017-04-26T20:55:31","modified_gmt":"2017-04-27T01:55:31","slug":"keystonejs-migrate-from-wordpress-prototype","status":"publish","type":"post","link":"https:\/\/blog.ls-al.com\/keystonejs-migrate-from-wordpress-prototype\/","title":{"rendered":"Keystonejs Migrate from WordPress Prototype"},"content":{"rendered":"

Since I put some effort into looking at possible solutions for blogging using Node\/MongoDB as underlying platform I am documenting a test I did with Keystonejs. It's website describes it as a Node.js CMS & Web Application Platform. <\/p>\n

Need Node.js 0.10+ and MongoDB v2.4+ and high level steps on Ubuntu 17.04 as follow:
\n1. Setup MongoDB from package management.
\n2. Install a current version of node in \/usr\/local. Not using the version from the Ubuntu repository.
\n3. Install keystonejs generator(using npm) and run generator(using yo).
\n4. Export WordPress xml.
\n5. Convert WordPress xml to MongoDB import format(json). Used python lxml.
\n6. Run mongo import of json<\/p>\n

STEP 1: Setup MongoDB from package management.<\/p>\n

\r\n# apt-get install -y mongodb-org\r\n# systemctl start mongod\r\n<\/pre>\n

STEP 2: Install a current version of node in \/usr\/local. Not using the version from the Ubuntu repository.
\nGrabbed from here: https:\/\/nodejs.org\/dist\/v7.9.0\/node-v7.9.0-linux-x64.tar.xz<\/p>\n

\r\n$ sudo mv node-v7.9.0-linux-x64\/ \/usr\/local\/\r\n$ export PATH=$PATH:\/usr\/local\/node-v7.9.0-linux-x64\/bin\r\n\r\n$ npm version\r\n{ npm: '4.2.0',\r\n<snip>\r\n\r\n$ node -v\r\nv7.9.0\r\n<\/pre>\n

STEP 3: Install keystonejs generator(using npm) and run generator(using yo). <\/p>\n

\r\n$ npm install -g generator-keystone\r\n$ npm install -g yo\r\n\r\n$ cd test-project\/\r\n$ yo keystone\r\nYour KeystoneJS project is ready to go!\r\n<snip>\r\n\r\n$ cd my-site\/\r\n$ node keystone\r\nApplying update 0.0.1-admins...\r\nSuccessfully created:\r\n*   1 User\r\nKeystoneJS Started:\r\nMy Site is ready on http:\/\/0.0.0.0:3000\r\n------------------------------------------------\r\n<\/pre>\n

STEP 4. Export WordPress xml.<\/p>\n

STEP 5: Convert WordPress xml to MongoDB import format(json). Used python lxml and input file riaan039ssysadminblog.wordpress.2017-04-25.xml.<\/p>\n

\r\n$ python xmlconvert6.py > 6.json\r\n<\/pre>\n

STEP 6: Run mongo import of json<\/p>\n

\r\n$ mongoimport --db my-site --collection posts  --drop --file 6.json\r\n<\/pre>\n

As mentioned this is a prototype and not really an option for me at this point. The xmlconvert.py script will need a lot of work to make the posts convert cleaner and keep formatting. Also this is not a full featured blog application like WordPress but rather just a framework to build on. So for me to replace my blogs I am missing things like code highlighting, permalinks etc<\/p>\n

Example code for WordPress xml to MongoDB import json format.<\/p>\n

\r\nimport xml.etree.ElementTree as ET\r\nfrom datetime import datetime\r\n#https:\/\/docs.python.org\/2\/library\/xml.etree.elementtree.html\r\n\r\n#### Get to this kind of format for mongo import\r\n#### { "slug" : "post-2", "title" : "Post 2", "categories" : [ ], "state" : "published", "__v" : 0, "content" : { "brief" : "<p>Blah 2<\/p>", "extended" : "" }, "publishedDate" : ISODate("2017-04-25T05:00:00Z") }\r\n\r\nit = ET.iterparse('riaan039ssysadminblog.wordpress.2017-04-25.xml')\r\nfor _, el in it:\r\n  #if "{http:\/\/wordpress.org\/export\/1.2\/}" in el.tag:\r\n  if "{" in el.tag:\r\n    el.tag = el.tag.split('}', 1)[1]  # strip all namespaces\r\n\r\ntree = it.root\r\n\r\nchannel = tree.find("channel")\r\n\r\ni=0\r\n\r\nfor item in channel.findall('item'):\r\n  i = i + 1\r\n  slug = 'slug' + str(i)\r\n  title = item.find('title').text\r\n  if not title:\r\n    title = 'no title'\r\n  title = title.replace('"','')\r\n  #<category domain="category" nicename="kvm"><![CDATA[KVM]]><\/category>\r\n  #<category domain="category" nicename="lvm"><![CDATA[LVM]]><\/category>\r\n  ## TBD: Convert categories just leaving empty for now\r\n  categories=[]\r\n\r\n  state=item.find('status').text\r\n  if state == "publish":\r\n    state = "published"\r\n  v=0\r\n\r\n  ## "content" : { "brief" : "<p>Test1 Brief<\/p>", "extended" : "<p>Test1 Extended<\/p>" }\r\n  content=item.find('encoded').text\r\n  if not content:\r\n    content=" "\r\n  content=content.encode('utf-8')\r\n  content=content.replace('\\n', '<br>')\r\n  content=content.replace('\\t', ' ')\r\n  #content=content.replace('<', ' ')\r\n  #content=content.replace('>', ' ')\r\n  #content=content.replace('<\/', '<\/\/')\r\n  content=content.replace('"', ' ')\r\n  content=content.replace("\\\\", "\/")   # This is a junk cheat for now.  Need a better way for C:\\Program Files\\...\r\n\r\n  content_brief=content[:30]\r\n  content_extended=content\r\n\r\n  ## Convert Tue, 06 Nov 2012 08:49:21 +0000 to look like this: ISODate("2017-04-25T05:00:00Z")\r\n  d2 = item.find('pubDate').text.split(' +0000')\r\n  d1 = d2[0].strip()\r\n  #######pubDate = item.get('pubDate')\r\n  #######publishedDate="2017-04-25T05:00:00Z"\r\n  #d = datetime.strptime(d1, '%a, %d %b %Y %H:%M:%S')\r\n  #publishedDate = d.strftime('%Y-%m-%dT%H:%M:%SZ')\r\n\r\n  # pubDate form WordPress xml had some odd dates that could not be used with strptime so using post_date\r\n  #<wp:post_date><![CDATA[2012-11-06 20:28:06]]><\/wp:post_date>\r\n  d1 = item.find('post_date').text \r\n  d = datetime.strptime(d1, '%Y-%m-%d %H:%M:%S')\r\n  publishedDate = d.strftime('%Y-%m-%dT%H:%M:%SZ')\r\n\r\n  print ' {{ "slug": "{}", "title": "{}", "categories": {}, "state": "{}", "__v": {}, "content": {{ "brief":"<p>{}<\/p>", "extended":"<p>{}<\/p>" }}, "publishedDate": ISODate("{}") }}'.format(slug, title, categories, state, v, content_brief, content_extended, publishedDate)\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"

Since I put some effort into looking at possible solutions for blogging using Node\/MongoDB as underlying platform I am documenting<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[84,83,85],"tags":[],"class_list":["post-1097","post","type-post","status-publish","format-standard","hentry","category-keystonejs","category-mean","category-node"],"_links":{"self":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts\/1097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/comments?post=1097"}],"version-history":[{"count":0,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/posts\/1097\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/media?parent=1097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/categories?post=1097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ls-al.com\/wp-json\/wp\/v2\/tags?post=1097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}