SlideShare uma empresa Scribd logo
1 de 37
Baixar para ler offline
Migrating From Drupal
    to Plone with
    Transmogrifier
   Clayton Parker, Senior Developer
       PLONE SYMPOSIUM EAST 2011
Who Am I?                 PLONE SYMPOSIUM EAST 2011




• claytron
• Python dev since 2003
• Plone Core Committer
• Foundation Member
What will we learn?            PLONE SYMPOSIUM EAST 2011




• Transmogrifier basics
• Migration Planning Process
• Creating a pipeline
Migrations                    PLONE SYMPOSIUM EAST 2011




• One off scripts
• In multiple places
• Little to no re-usability
Transmogrifier                  PLONE SYMPOSIUM EAST 2011




• A framework for migrations
• Re-usable parts
Basics         PLONE SYMPOSIUM EAST 2011




• Pipeline
• Blueprints
• Sources
• Section
Sources                         PLONE SYMPOSIUM EAST 2011




• A blueprint
• First item in your pipeline
Example Pipeline                                PLONE SYMPOSIUM EAST 2011




 [transmogrifier]
 pipeline =
     csv_file
     constructor
     schemaupdater
        <html>
        <body>
 [csv_file]
        <h3>Code Sample</h3>
 blueprint = collective.transmogrifier.sections.csvsource
        <p>Replace this text!</p>
 filename = my.migration.import:my_items.csv
        </body>
        </html>
 [constructor]
 blueprint = collective.transmogrifier.sections.constructor

 [schemaupdater]
 blueprint = plone.app.transmogrifier.atschemaupdater
my_items.csv                                                 PLONE SYMPOSIUM EAST 2011




_path          ,   _type      ,   title           ,   description
/folder1       ,   Folder     ,   First Folder    ,   This is folder One
/folder2       ,   Folder     ,   Second Folder   ,   This is folder Two
/folder1/foo   ,   Document   ,   One Foo         ,   A document named foo
/folder2/foo   ,   Document   ,   Two Foo         ,   Another doc named foo
The Result   PLONE SYMPOSIUM EAST 2011
Items                                    PLONE SYMPOSIUM EAST 2011




• Each item is a mapping
• Keys are fields
• Keys with a leading underscore are controllers
Example Item                                       PLONE SYMPOSIUM EAST 2011




{'_id': 'a-stronger-connection-to-out-customers',
 '_path': 'content/stronger-connection-out-customers',
 '_status': 1L,
 '_text_mimetype': 'text/html',
 '_transitions': 'publish',
 '_type': 'Document',
 'allowDiscussion': False,
 'creation_date': '2011/05/14 9:20:50',
 'effectiveDate': '2011/05/14 9:20:50',
 'modification_date': '2011/05/18 9:22:22',
 'subject': 'betterninterestingnstronger',
 'text': '<p>this is some text</p>rn',
 'title': 'A stronger connection to out customers'}
Migration Strategy                PLONE SYMPOSIUM EAST 2011




• Investigate the source
• Prepare the destination
• Find Transmogrifier blueprints
• Write the pipeline
Write your own         PLONE SYMPOSIUM EAST 2011




• Missing blueprint
• Write one
• Contribute it back
GenericSetup                            PLONE SYMPOSIUM EAST 2011




• Make migration part of your release
• Ability to package migrations
My Migration                PLONE SYMPOSIUM EAST 2011




• Drupal backed by MySQL
• transmogrify.sqlalchemy
• Plone 4.0.5
• collective.blog.star
• plone.app.discussion
Package Layout                               PLONE SYMPOSIUM EAST 2011


    my.migration
    !"" my
    #   !"" __init__.py
    #   %"" migration
    #       !"" __init__.py
    #       !"" config
    #       #   !"" articles.cfg
    #       #   !"" base.cfg
    #       #   !"" blogs.cfg
    #       #   !"" comments.cfg
    #       #   %"" pages.cfg
    #       !"" configure.zcml
    #       %"" profiles
    #           %"" default
    #               !"" metadata.xml
    #               %"" transmogrifier.txt
    !"" setup.cfg
    %"" setup.py
Registering Configs                               PLONE SYMPOSIUM EAST 2011




<transmogrifier:registerConfig
    name="my.migration.base"
    title="My migration base config"
    description="Base settings for all transmogrifier imports"
    configuration="config/base.cfg"
    />
Registering Configs                               PLONE SYMPOSIUM EAST 2011




<transmogrifier:registerConfig
    name="my.migration.pages"
    title="Drupal pages"
    description="Import pages from Drupal into Plone"
    configuration="config/pages.cfg"
    />
Registering Configs                               PLONE SYMPOSIUM EAST 2011




<transmogrifier:registerConfig
    name="my.migration.articles"
    title="Drupal articles"
    description="Import articles from Drupal into Plone"
    configuration="config/articles.cfg"
    />
Registering Configs                               PLONE SYMPOSIUM EAST 2011




<transmogrifier:registerConfig
    name="my.migration.blogs"
    title="Drupal blog entries"
    description="Import blog entries from Drupal into Plone"
    configuration="config/blogs.cfg"
    />
Registering Configs                               PLONE SYMPOSIUM EAST 2011




<transmogrifier:registerConfig
    name="my.migration.comments"
    title="Drupal comments"
    description="Import comments from Drupal into Plone"
    configuration="config/comments.cfg"
    />
transmogrifier.txt           PLONE SYMPOSIUM EAST 2011




    my.migration.pages
    my.migration.articles
    my.migration.blogs
    my.migration.comments
Package Layout                               PLONE SYMPOSIUM EAST 2011


    my.migration
    !"" my
    #   !"" __init__.py
    #   %"" migration
    #       !"" __init__.py
    #       !"" config
    #       #   !"" articles.cfg
    #       #   !"" base.cfg
    #       #   !"" blogs.cfg
    #       #   !"" comments.cfg
    #       #   %"" pages.cfg
    #       !"" configure.zcml
    #       %"" profiles
    #           %"" default
    #               !"" metadata.xml
    #               %"" transmogrifier.txt
    !"" setup.cfg
    %"" setup.py
base.cfg pipeline                                   PLONE SYMPOSIUM EAST 2011


    [transmogrifier]
    pipeline =
        drupal
        portal_type
        url_normalizer
        path
        publication_state
        text_mimetype
        mimetype_encapsulator
        folders
        constructor
        commenting
        comments
        schema_update
        workflow
        reindex_object

    [settings]
    # Path to use if there isn’t one given
    base_path = other-content
    # Have to escape python string formatting for when
    # this gets passed into sqlalchemy
    date_format = %%Y/%%m/%%d %%k:%%i:%%s
drupal section                                 PLONE SYMPOSIUM EAST 2011




  [drupal]
  blueprint = transmogrify.sqlalchemy
  dsn = mysql://user:password@localhost/drupal-transmog
articles.cfg                                                                PLONE SYMPOSIUM EAST 2011



 [transmogrifier]
 include = my.migration.base

 [drupal]
 query =
 	 SELECT
 	 	 node.title,
 	 	 node.status AS status,
 	 	 GROUP_CONCAT(tag_data.name SEPARATOR 'n') AS subject,
 	 	 FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date,
 	 	 FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate,
 	 	 FROM_UNIXTIME(node.changed, "${settings:date_format}") AS modification_date,
 	 	 body_data.body_value AS text
 	 	 url_alias.alias AS _path
 	 FROM node
       INNER JOIN field_data_field_tags AS tag_field ON tag_field.entity_id = node.nid
       INNER JOIN taxonomy_term_data AS tag_data ON tag_data.tid = tag_field.field_tags_tid
       INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid
       INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid)
 	 GROUP BY
 	 	 node.title,
 	 	 node.status,
 	 	 node.created,
 	 	 node.changed,
 	 	 body_data.body_value,
 	 	 url_alias.alias;

 [portal_type]
 value = string:Document
pages.cfg                                                                   PLONE SYMPOSIUM EAST 2011



  [transmogrifier]
  include = my.migration.base

  [drupal]
  query =
  	 my.migration.base
  	 SELECT
  	 	     node.title,
           node.status AS _status,
           FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date,
           FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate,
           FROM_UNIXTIME(node.changed, "${settings:date_format}") AS modification_date,
  	 	     body_data.body_value AS text,
  	 	     url_alias.alias AS _path
  	 FROM node
           INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid
           INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid)
      WHERE node.type = "page"
  	 GROUP BY
  	       node.title,
  	 	     node.status,
  	 	     node.created,
  	 	     node.changed,
  	 	     body_data.body_value,
  	 	     url_alias.alias;	 	

  [portal_type]
  value = string:Document
blogs.cfg                                                                   PLONE SYMPOSIUM EAST 2011


  [transmogrifier]
  include = my.migration.base

  [drupal]
  query =
      SELECT
           node.title,
           node.satus AS _status,
           FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date,
           FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate,
           FROM_UNIXTIME(node.created, "${settings:date_format}") AS modification_date,
           body_data.body_value AS text,
           url_alias.alias AS _path
      FROM node
           INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid
           INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid)
      WHERE node.type = "blog"
      GROUP BY
           node.title,
           node.status,
           node.created,
           node.changed,
           body_data.body_value,
           url_alias.alias;

  [portal_type]
  value = string:BlogEntry

  [commenting]
  value = python:True
comments.cfg                                                               PLONE SYMPOSIUM EAST 2011


 [transmogrifier]
 include = my.migration.base

 [drupal]
 query =
     my.migration.base
     SELECT
          comment.subject AS title,
          FROM_UNIXTIME(comment.created, "${settings:date_format}") AS published,
          FROM_UNIXTIME(comment.changed, "${settings:date_format}") AS updated,
          comment.name AS author_name,
          body_data.comment_body_value AS text,
          url_alias.alias AS _parent_path
     FROM comment
          INNER JOIN field_data_comment_body AS body_data ON body_data.entity_id =
 comment.cid
          INNER JOIN node ON node.nid = comment.nid
          INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid)
     GROUP BY
          comment.subject,
          comment.created,
          comment.changed,
          comment.name,
          body_data.comment_body_value,
          url_alias.alias;

 [portal_type]
 # Override the portal type to use the "comment_type"
 key = string:_comment_type
 value = string:plone.app.discussion
base.cfg overrides                                         PLONE SYMPOSIUM EAST 2011




 [path]
 blueprint = collective.transmogrifier.sections.inserter
 # only add a path if one does not exist
 condition = python:'_path' not in item and not '_parent_path' in item
 key = string:_path
 # Add the value in the extended configuration
 value = string:${settings:base_path}/${item/_id}

 [portal_type]
 blueprint = collective.transmogrifier.sections.inserter
 key = string:_type
 # We will add the value in the extended config, but we need a
 # default set here
 value = string:

 [commenting]
 blueprint = collective.transmogrifier.sections.inserter
 key = string:allowDiscussion
 # default to false
 value = python:False
Content Creation                                          PLONE SYMPOSIUM EAST 2011




 [comments]
 blueprint = transmogrify.comments

 [folders]
 blueprint = collective.transmogrifier.sections.folders

 [constructor]
 blueprint = collective.transmogrifier.sections.constructor

 [schema_update]
 blueprint = plone.app.transmogrifier.atschemaupdater

 [workflow]
 blueprint = plone.app.transmogrifier.workflowupdater

 [reindex_object]
 blueprint = plone.app.transmogrifier.reindexobject
Item Modification                                         PLONE SYMPOSIUM EAST 2011




 [publication_state]
 blueprint = collective.transmogrifier.sections.inserter
 condition = python:'_status' in item and item['_status'] == 1
 key = string:_transitions
 value = string:publish

 [text_mimetype]
 # This could probably be taken from the database as well
 blueprint = collective.transmogrifier.sections.inserter
 key = string:_text_mimetype
 value = string:text/html

 [mimetype_encapsulator]
 blueprint = plone.app.transmogrifier.mimeencapsulator
 key = text
 mimetype = python:item.get('_%s_mimetype', key)
 field = key
 condition = mimetype
PLONE SYMPOSIUM EAST 2011




DEMO
Links                                              PLONE SYMPOSIUM EAST 2011




• collective.transmogrifier
http://pypi.python.org/pypi/collective.transmogrifier/

• plone.app.transmogrifier
http://pypi.python.org/pypi/plone.app.transmogrifier/
Useful Sources and            PLONE SYMPOSIUM EAST 2011



Blueprints
• plone.app.transmogrifier
• transmogrify.filesystem
• transmogrify.sqlalchemy
• transmogrify.webcrawler
• quintagroup.transmogrifier
• transmogrify.comments
Check out
          .co m/d emos
s ixfeetup

Mais conteúdo relacionado

Mais procurados

Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank Müller
 
What's new in PHP 5.5
What's new in PHP 5.5What's new in PHP 5.5
What's new in PHP 5.5Tom Corrigan
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid themSteven Francia
 
A new way to develop with WordPress!
A new way to develop with WordPress!A new way to develop with WordPress!
A new way to develop with WordPress!David Sanchez
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring ClojurescriptLuke Donnet
 
Node.js basics
Node.js basicsNode.js basics
Node.js basicsBen Lin
 
The GO Language : From Beginners to Gophers
The GO Language : From Beginners to GophersThe GO Language : From Beginners to Gophers
The GO Language : From Beginners to GophersAlessandro Sanino
 
Groovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web ApplicationsGroovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web Applicationsrohitnayak
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in goborderj
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRAMBLER&Co
 
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...Anton
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 

Mais procurados (20)

Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
What's new in PHP 5.5
What's new in PHP 5.5What's new in PHP 5.5
What's new in PHP 5.5
 
PHP7 Presentation
PHP7 PresentationPHP7 Presentation
PHP7 Presentation
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them
 
A new way to develop with WordPress!
A new way to develop with WordPress!A new way to develop with WordPress!
A new way to develop with WordPress!
 
The new features of PHP 7
The new features of PHP 7The new features of PHP 7
The new features of PHP 7
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Node.js basics
Node.js basicsNode.js basics
Node.js basics
 
New Design of OneRing
New Design of OneRingNew Design of OneRing
New Design of OneRing
 
Testing con spock
Testing con spockTesting con spock
Testing con spock
 
The GO Language : From Beginners to Gophers
The GO Language : From Beginners to GophersThe GO Language : From Beginners to Gophers
The GO Language : From Beginners to Gophers
 
Groovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web ApplicationsGroovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web Applications
 
Txjs
TxjsTxjs
Txjs
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по Dip
 
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
 
groovy & grails - lecture 4
groovy & grails - lecture 4groovy & grails - lecture 4
groovy & grails - lecture 4
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 

Semelhante a Migrating from drupal to plone with transmogrifier

Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsDylan Jay
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Hugo Hamon
 
Drupal 8 Configuration Management
Drupal 8 Configuration ManagementDrupal 8 Configuration Management
Drupal 8 Configuration ManagementPhilip Norton
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)Beau Lebens
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Flask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsFlask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsAlex Eftimie
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPDan Jesus
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to TornadoGavin Roy
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4DEVCON
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node jsfakedarren
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
Twas the night before Malware...
Twas the night before Malware...Twas the night before Malware...
Twas the night before Malware...DoktorMandrake
 
Drupal 8 configuration management
Drupal 8 configuration managementDrupal 8 configuration management
Drupal 8 configuration managementAlexander Tkachev
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2Paras Mendiratta
 

Semelhante a Migrating from drupal to plone with transmogrifier (20)

Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Drupal 8 Configuration Management
Drupal 8 Configuration ManagementDrupal 8 Configuration Management
Drupal 8 Configuration Management
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Flask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshopsFlask intro - ROSEdu web workshops
Flask intro - ROSEdu web workshops
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Twas the night before Malware...
Twas the night before Malware...Twas the night before Malware...
Twas the night before Malware...
 
Drupal 8 configuration management
Drupal 8 configuration managementDrupal 8 configuration management
Drupal 8 configuration management
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2
 

Mais de Clayton Parker

Customizing Your Shell With Dotfiles
Customizing Your Shell With DotfilesCustomizing Your Shell With Dotfiles
Customizing Your Shell With DotfilesClayton Parker
 
Fuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy MatchingFuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy MatchingClayton Parker
 
Exploring Code with Pry!
Exploring Code with Pry!Exploring Code with Pry!
Exploring Code with Pry!Clayton Parker
 
Zen and the Art of Python
Zen and the Art of PythonZen and the Art of Python
Zen and the Art of PythonClayton Parker
 
So you think you can pdb?
So you think you can pdb?So you think you can pdb?
So you think you can pdb?Clayton Parker
 
Managing Chaos: Merging 120 Sites into a single Plone Multisite Solution
Managing Chaos: Merging 120 Sites into a single Plone Multisite SolutionManaging Chaos: Merging 120 Sites into a single Plone Multisite Solution
Managing Chaos: Merging 120 Sites into a single Plone Multisite SolutionClayton Parker
 
Current State of Python Packaging
Current State of Python PackagingCurrent State of Python Packaging
Current State of Python PackagingClayton Parker
 
Notre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with LineageNotre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with LineageClayton Parker
 
Pioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with PlonePioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with PloneClayton Parker
 
Using Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the WorldUsing Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the WorldClayton Parker
 
Make Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using SolrMake Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using SolrClayton Parker
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the FutureClayton Parker
 
LDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in PloneLDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in PloneClayton Parker
 
Code with Style - PyOhio
Code with Style - PyOhioCode with Style - PyOhio
Code with Style - PyOhioClayton Parker
 
Using Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsUsing Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsClayton Parker
 
Generic Setup De-Mystified
Generic Setup De-MystifiedGeneric Setup De-Mystified
Generic Setup De-MystifiedClayton Parker
 
Buildout: Fostering Repeatability
Buildout: Fostering RepeatabilityBuildout: Fostering Repeatability
Buildout: Fostering RepeatabilityClayton Parker
 

Mais de Clayton Parker (20)

Customizing Your Shell With Dotfiles
Customizing Your Shell With DotfilesCustomizing Your Shell With Dotfiles
Customizing Your Shell With Dotfiles
 
Vim for Mere Mortals
Vim for Mere MortalsVim for Mere Mortals
Vim for Mere Mortals
 
Fuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy MatchingFuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy Matching
 
Exploring Code with Pry!
Exploring Code with Pry!Exploring Code with Pry!
Exploring Code with Pry!
 
Zen and the Art of Python
Zen and the Art of PythonZen and the Art of Python
Zen and the Art of Python
 
So you think you can pdb?
So you think you can pdb?So you think you can pdb?
So you think you can pdb?
 
Managing Chaos: Merging 120 Sites into a single Plone Multisite Solution
Managing Chaos: Merging 120 Sites into a single Plone Multisite SolutionManaging Chaos: Merging 120 Sites into a single Plone Multisite Solution
Managing Chaos: Merging 120 Sites into a single Plone Multisite Solution
 
Current State of Python Packaging
Current State of Python PackagingCurrent State of Python Packaging
Current State of Python Packaging
 
Notre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with LineageNotre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with Lineage
 
Pioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with PlonePioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with Plone
 
Using Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the WorldUsing Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the World
 
Make Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using SolrMake Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using Solr
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the Future
 
Buildout future
Buildout futureBuildout future
Buildout future
 
LDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in PloneLDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in Plone
 
Code with Style - PyOhio
Code with Style - PyOhioCode with Style - PyOhio
Code with Style - PyOhio
 
Code with style
Code with styleCode with style
Code with style
 
Using Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsUsing Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python Projects
 
Generic Setup De-Mystified
Generic Setup De-MystifiedGeneric Setup De-Mystified
Generic Setup De-Mystified
 
Buildout: Fostering Repeatability
Buildout: Fostering RepeatabilityBuildout: Fostering Repeatability
Buildout: Fostering Repeatability
 

Último

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 

Último (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Migrating from drupal to plone with transmogrifier

  • 1. Migrating From Drupal to Plone with Transmogrifier Clayton Parker, Senior Developer PLONE SYMPOSIUM EAST 2011
  • 2. Who Am I? PLONE SYMPOSIUM EAST 2011 • claytron • Python dev since 2003 • Plone Core Committer • Foundation Member
  • 3. What will we learn? PLONE SYMPOSIUM EAST 2011 • Transmogrifier basics • Migration Planning Process • Creating a pipeline
  • 4. Migrations PLONE SYMPOSIUM EAST 2011 • One off scripts • In multiple places • Little to no re-usability
  • 5. Transmogrifier PLONE SYMPOSIUM EAST 2011 • A framework for migrations • Re-usable parts
  • 6. Basics PLONE SYMPOSIUM EAST 2011 • Pipeline • Blueprints • Sources • Section
  • 7. Sources PLONE SYMPOSIUM EAST 2011 • A blueprint • First item in your pipeline
  • 8. Example Pipeline PLONE SYMPOSIUM EAST 2011 [transmogrifier] pipeline = csv_file constructor schemaupdater <html> <body> [csv_file] <h3>Code Sample</h3> blueprint = collective.transmogrifier.sections.csvsource <p>Replace this text!</p> filename = my.migration.import:my_items.csv </body> </html> [constructor] blueprint = collective.transmogrifier.sections.constructor [schemaupdater] blueprint = plone.app.transmogrifier.atschemaupdater
  • 9. my_items.csv PLONE SYMPOSIUM EAST 2011 _path , _type , title , description /folder1 , Folder , First Folder , This is folder One /folder2 , Folder , Second Folder , This is folder Two /folder1/foo , Document , One Foo , A document named foo /folder2/foo , Document , Two Foo , Another doc named foo
  • 10. The Result PLONE SYMPOSIUM EAST 2011
  • 11. Items PLONE SYMPOSIUM EAST 2011 • Each item is a mapping • Keys are fields • Keys with a leading underscore are controllers
  • 12. Example Item PLONE SYMPOSIUM EAST 2011 {'_id': 'a-stronger-connection-to-out-customers', '_path': 'content/stronger-connection-out-customers', '_status': 1L, '_text_mimetype': 'text/html', '_transitions': 'publish', '_type': 'Document', 'allowDiscussion': False, 'creation_date': '2011/05/14 9:20:50', 'effectiveDate': '2011/05/14 9:20:50', 'modification_date': '2011/05/18 9:22:22', 'subject': 'betterninterestingnstronger', 'text': '<p>this is some text</p>rn', 'title': 'A stronger connection to out customers'}
  • 13. Migration Strategy PLONE SYMPOSIUM EAST 2011 • Investigate the source • Prepare the destination • Find Transmogrifier blueprints • Write the pipeline
  • 14. Write your own PLONE SYMPOSIUM EAST 2011 • Missing blueprint • Write one • Contribute it back
  • 15. GenericSetup PLONE SYMPOSIUM EAST 2011 • Make migration part of your release • Ability to package migrations
  • 16. My Migration PLONE SYMPOSIUM EAST 2011 • Drupal backed by MySQL • transmogrify.sqlalchemy • Plone 4.0.5 • collective.blog.star • plone.app.discussion
  • 17. Package Layout PLONE SYMPOSIUM EAST 2011 my.migration !"" my #   !"" __init__.py #   %"" migration #   !"" __init__.py #   !"" config #   #   !"" articles.cfg #   #   !"" base.cfg #   #   !"" blogs.cfg #   #   !"" comments.cfg #   #   %"" pages.cfg #   !"" configure.zcml #   %"" profiles #      %"" default #      !"" metadata.xml #      %"" transmogrifier.txt !"" setup.cfg %"" setup.py
  • 18. Registering Configs PLONE SYMPOSIUM EAST 2011 <transmogrifier:registerConfig name="my.migration.base" title="My migration base config" description="Base settings for all transmogrifier imports" configuration="config/base.cfg" />
  • 19. Registering Configs PLONE SYMPOSIUM EAST 2011 <transmogrifier:registerConfig name="my.migration.pages" title="Drupal pages" description="Import pages from Drupal into Plone" configuration="config/pages.cfg" />
  • 20. Registering Configs PLONE SYMPOSIUM EAST 2011 <transmogrifier:registerConfig name="my.migration.articles" title="Drupal articles" description="Import articles from Drupal into Plone" configuration="config/articles.cfg" />
  • 21. Registering Configs PLONE SYMPOSIUM EAST 2011 <transmogrifier:registerConfig name="my.migration.blogs" title="Drupal blog entries" description="Import blog entries from Drupal into Plone" configuration="config/blogs.cfg" />
  • 22. Registering Configs PLONE SYMPOSIUM EAST 2011 <transmogrifier:registerConfig name="my.migration.comments" title="Drupal comments" description="Import comments from Drupal into Plone" configuration="config/comments.cfg" />
  • 23. transmogrifier.txt PLONE SYMPOSIUM EAST 2011 my.migration.pages my.migration.articles my.migration.blogs my.migration.comments
  • 24. Package Layout PLONE SYMPOSIUM EAST 2011 my.migration !"" my #   !"" __init__.py #   %"" migration #   !"" __init__.py #   !"" config #   #   !"" articles.cfg #   #   !"" base.cfg #   #   !"" blogs.cfg #   #   !"" comments.cfg #   #   %"" pages.cfg #   !"" configure.zcml #   %"" profiles #      %"" default #      !"" metadata.xml #      %"" transmogrifier.txt !"" setup.cfg %"" setup.py
  • 25. base.cfg pipeline PLONE SYMPOSIUM EAST 2011 [transmogrifier] pipeline = drupal portal_type url_normalizer path publication_state text_mimetype mimetype_encapsulator folders constructor commenting comments schema_update workflow reindex_object [settings] # Path to use if there isn’t one given base_path = other-content # Have to escape python string formatting for when # this gets passed into sqlalchemy date_format = %%Y/%%m/%%d %%k:%%i:%%s
  • 26. drupal section PLONE SYMPOSIUM EAST 2011 [drupal] blueprint = transmogrify.sqlalchemy dsn = mysql://user:password@localhost/drupal-transmog
  • 27. articles.cfg PLONE SYMPOSIUM EAST 2011 [transmogrifier] include = my.migration.base [drupal] query = SELECT node.title, node.status AS status, GROUP_CONCAT(tag_data.name SEPARATOR 'n') AS subject, FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date, FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate, FROM_UNIXTIME(node.changed, "${settings:date_format}") AS modification_date, body_data.body_value AS text url_alias.alias AS _path FROM node INNER JOIN field_data_field_tags AS tag_field ON tag_field.entity_id = node.nid INNER JOIN taxonomy_term_data AS tag_data ON tag_data.tid = tag_field.field_tags_tid INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid) GROUP BY node.title, node.status, node.created, node.changed, body_data.body_value, url_alias.alias; [portal_type] value = string:Document
  • 28. pages.cfg PLONE SYMPOSIUM EAST 2011 [transmogrifier] include = my.migration.base [drupal] query = my.migration.base SELECT node.title, node.status AS _status, FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date, FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate, FROM_UNIXTIME(node.changed, "${settings:date_format}") AS modification_date, body_data.body_value AS text, url_alias.alias AS _path FROM node INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid) WHERE node.type = "page" GROUP BY node.title, node.status, node.created, node.changed, body_data.body_value, url_alias.alias; [portal_type] value = string:Document
  • 29. blogs.cfg PLONE SYMPOSIUM EAST 2011 [transmogrifier] include = my.migration.base [drupal] query = SELECT node.title, node.satus AS _status, FROM_UNIXTIME(node.created, "${settings:date_format}") AS creation_date, FROM_UNIXTIME(node.created, "${settings:date_format}") AS effectiveDate, FROM_UNIXTIME(node.created, "${settings:date_format}") AS modification_date, body_data.body_value AS text, url_alias.alias AS _path FROM node INNER JOIN field_data_body AS body_data ON body_data.entity_id = node.nid INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid) WHERE node.type = "blog" GROUP BY node.title, node.status, node.created, node.changed, body_data.body_value, url_alias.alias; [portal_type] value = string:BlogEntry [commenting] value = python:True
  • 30. comments.cfg PLONE SYMPOSIUM EAST 2011 [transmogrifier] include = my.migration.base [drupal] query = my.migration.base SELECT comment.subject AS title, FROM_UNIXTIME(comment.created, "${settings:date_format}") AS published, FROM_UNIXTIME(comment.changed, "${settings:date_format}") AS updated, comment.name AS author_name, body_data.comment_body_value AS text, url_alias.alias AS _parent_path FROM comment INNER JOIN field_data_comment_body AS body_data ON body_data.entity_id = comment.cid INNER JOIN node ON node.nid = comment.nid INNER JOIN url_alias ON url_alias.source = CONCAT("node/", node.nid) GROUP BY comment.subject, comment.created, comment.changed, comment.name, body_data.comment_body_value, url_alias.alias; [portal_type] # Override the portal type to use the "comment_type" key = string:_comment_type value = string:plone.app.discussion
  • 31. base.cfg overrides PLONE SYMPOSIUM EAST 2011 [path] blueprint = collective.transmogrifier.sections.inserter # only add a path if one does not exist condition = python:'_path' not in item and not '_parent_path' in item key = string:_path # Add the value in the extended configuration value = string:${settings:base_path}/${item/_id} [portal_type] blueprint = collective.transmogrifier.sections.inserter key = string:_type # We will add the value in the extended config, but we need a # default set here value = string: [commenting] blueprint = collective.transmogrifier.sections.inserter key = string:allowDiscussion # default to false value = python:False
  • 32. Content Creation PLONE SYMPOSIUM EAST 2011 [comments] blueprint = transmogrify.comments [folders] blueprint = collective.transmogrifier.sections.folders [constructor] blueprint = collective.transmogrifier.sections.constructor [schema_update] blueprint = plone.app.transmogrifier.atschemaupdater [workflow] blueprint = plone.app.transmogrifier.workflowupdater [reindex_object] blueprint = plone.app.transmogrifier.reindexobject
  • 33. Item Modification PLONE SYMPOSIUM EAST 2011 [publication_state] blueprint = collective.transmogrifier.sections.inserter condition = python:'_status' in item and item['_status'] == 1 key = string:_transitions value = string:publish [text_mimetype] # This could probably be taken from the database as well blueprint = collective.transmogrifier.sections.inserter key = string:_text_mimetype value = string:text/html [mimetype_encapsulator] blueprint = plone.app.transmogrifier.mimeencapsulator key = text mimetype = python:item.get('_%s_mimetype', key) field = key condition = mimetype
  • 34. PLONE SYMPOSIUM EAST 2011 DEMO
  • 35. Links PLONE SYMPOSIUM EAST 2011 • collective.transmogrifier http://pypi.python.org/pypi/collective.transmogrifier/ • plone.app.transmogrifier http://pypi.python.org/pypi/plone.app.transmogrifier/
  • 36. Useful Sources and PLONE SYMPOSIUM EAST 2011 Blueprints • plone.app.transmogrifier • transmogrify.filesystem • transmogrify.sqlalchemy • transmogrify.webcrawler • quintagroup.transmogrifier • transmogrify.comments
  • 37. Check out .co m/d emos s ixfeetup