This question already has an answer here:
Can buildout create content as part of a Plone install?
(1 answer)
Closed 9 years ago.
I'm loosely following Martin Aspeli's book Professional Plone 4 Development and have a repeatable deployment using buildout. In order to make everything completely automated, I'd like to be able to run bin/buildout and find the site working with all the right add-ons activated. For example, I'm using collective.blog.star, and at present, I have to log into the site and activate it to be able to add blog views, etc..
How can I make buildout also activate the add-ons it downloads in a particular Plone site object?
As Martijn also writes, the quickinstaller takes care of this and it's merely a simple declaration of a dependency you can do in your package, to have the product installed on site-creation automagically, which takes two simple steps:
In the your.package/setup.py add:
setup( ...
install_requires=[ ...
'collective.blog.star'
To let buildout know, this egg shall be pulled and be provided to the ZOPE-instance, too.
And in your.package/your/package/profiles/default/metadata.xml add:
<object ... >
<dependencies>
<dependency>profile:collective.blog.star:default<dependency>
<dependencies>
To actually activate the dependency-product, when you install your product, via profiles.
Check if the profile's name is really 'default' as this is just a convention, defined in the configure.zcml of the product.
It might be, that the order of install can be crucial, as you also want to create content in the same process, I don't know by heart which step would be executed first, the c.b.star-install or the content-creation, you have to test this. In case, the order isn't right, you'd probably have to write another package for splitting the two tasks, controlling the order of install according to the position in the eggs-definitions-list (first comes first, IIRC).
Related
On a website with software documentation, I need to create a new version for a node always that the information changes for a new software release.
Here is an example:
For the product x version 1.0, I have a node (ID: 1000) that explains how to install the product.
When this product has a new release, the instructions need to change. Currently, what I do is to create a different node (ID: 1001) for product x version 2.0, also called how to install. The issue is that, since these two nodes are totally disconnected, as my database grows, managing these versions is getting too painful.
Ideally, I wouldn't have totally disconnected nodes for the same kind of information, but version that node as the product version changes. Is there any module that allows me to do it? If not, any idea on how to solve the issue?
Thank you
It sounds like you want to use node revisioning
https://www.drupal.org/node/320614
My approach would be to use a makeshift solution via entity reference and/or Rules. On a similar project, we used the Rules Link module to remove the author/ownership of the post but keep a reference for later processing by cloning the user entity in said rule to another field.
You could do the same: Automatically generate a new node with a reference to the old one and maybe copies of certain fields.
Depending on how much content you want to reuse, there's the Node Clone module and the Node clone on Save project seems like a fitting case, too (didn't test it).
Before the entity reference module got to be so mighty in Drupal 7 I often heard that sharing a common taxonomy term between 2 nodes would be another easy way to keep nodes „bundled“ – I'm not sure about the UX implications though.
Sorry, seeing that you're talking about documentation, another solution would be to simply activate the Books module and define a book for each product with the different versions as pages (see Drupal documentation as reference – you can easily style the structure, e.g. as tabs).
The module uses the menu system (up to Drupal 7) to keep a simple structure on top of the existing nodes. This approach has its UX limits on very large node counts.
Using the Book Made Simple module you can automatically generate a book on node creation.
My package introduces registry entries. Changes by site administrator should not be overwritten on reinstall of the package.
Many ways to Rome. I chose ftw.upgrade. I like the declarative way of the upgrade step syntax. Its possible to use an upgrade directory for generic setup xml-Files like propertiestool.xml. No need to define handler python code. The upgrade works well. The admin can upgrade from control panel and in my case the new property is added. Insomma: For a new property just these have to be added: an upgrade-step declaration for source and destination version and directory where to find the properties.xml. Thumb up! –
You can pilot what to do when installing a Plone add-on by providing an Extension/install.py file with a install method inside:
def install(portal, reinstall=False):
if not reinstall:
setup_tool = portal.portal_setup
setup_tool.runAllImportStepsFromProfile('profile-your.pfile:default')
This way you are driving what Plone should do when installing.
If you need it: the same if for uninstall:
def uninstall(portal, reinstall=False):
if not reinstall:
setup_tool = portal.portal_setup
setup_tool.runAllImportStepsFromProfile('profile-example.gs:uninstall')
This way you can prevent the uninstall step to be run when reinstalling.
Warning: as Mathias suggested using quickinstaller -> reinstall feature is bad.
Warning: this will not probably work anymore on Plone 5 (there's open discussion about this).
I think what you describe is one of the problems upcoming with the increasing complexity of Plone's stack, and one of the reasons, why it is not recommended to execute a re-install anymore, but to provide a profile for each version of the Add-On, via upgrade-steps (as Mathias mentioned). That increases dev-time significantly and results in even more conflicts, of my experience. Here are the refering docs:
http://docs.plone.org/develop/addons/components/genericsetup.html#add-upgrade-step
Elizabeth Leddy once wrote an Add-On to ease that pain and I can confirm it does:
https://github.com/ampsport/amp.ezupgrade
And the great guys from FTW, too, I never used it, but looks promising:
https://pypi.python.org/pypi/ftw.upgrade
Neither used this one, even claims to have some extra goodies, like cleanup broken OFS objects and R. Patterson's on it:
https://github.com/collective/collective.upgrade
As we're here, the first good doc I could find about it ~ 1.5 years ago, comes from Uwosh, of course:
http://www.uwosh.edu/ploneprojects/docs/how-tos/how-to-use-generic-setup-upgrade-steps
Another solution can be, to check, if it's an initial- or re-install, and set the properties programatically via a Python-script, conveniently called 'setuphandlers.py', like described in this answer:
How to check, if my product is already installed, when installing it?
That way one can still trigger re-installs without blowing it all up.
Lastly, a lot of the GS-xml-files understand the purge-property, setting it to False, will not overwrite the whole file, just your given props. This might, or not, apply to your case, you can find samples in the above referenced official doc.
I have a website that I need to deploy to about 30 customers. They are all the same apart from the branding. Using SVN, I would like to have one base version of the product, and then just the different branded content (images, CSS) for each customer. That way, when I maintain the base product, I don’t have to replicate that change for each customer. Deployment would just be a case of updating and releasing.
Sounds simple, but I am having problems achieving this in SVN. I have been looking into SVN externals using a structure as follows:
Main
Base
.
.
Images
Customer 1
Base
Custom
Images
Customer 2
Base
Custom
Images
and then using externals pointing the Customer Base folders to the main base folder. That works, but I then need to overwrite (for example) the images in the Customer 1\Base\Images folder with the customer specific ones, and when I set up the externals for that it complains “Customer 1\Base\Images is not a working copy root”. It does appear to have overwritten the image with the customer one though.
Maybe externals are not the answer.
In your case, the interface is clearly separeted from the functionality. A possibility is the following (if I well understood your problem) :
Manage your application in a dedicated SVN repository (as usual, with your trunk, branches and tags). And manage your design versions in another repository, with for example the following structure :
./Customer_1
./Customer_1/trunk
./Customer_1/tags
./Customer_1/branches
./Customer_2
./Customer_2/trunk
./Customer_2/tags
./Customer_2/branches
...
With this separation, it's easy to you to manage the version number of your main application. And you have a "small" repository for each customer with possibility to easily copy a design version to start another one by svn copy.
first of all, i will explain what i would like to do here : given a C big programm, i would like to output a list of producers/consumers for a data and a list of calling/called-by functions of the function where this data is.
for doing this, i am thinking about using what computes some modules of frama-c, like dataflow.ml or callgraph.ml in my own plugin.
however, as i read the plugin developper doc, i can't manage to see how we can have access to the data of those modules.
is a "open.cyl_type" sufficient here in my own plugin?
moreover, here are my other questions :
i tried using by the way pdg plugin for my purposes but when i call it and it says "pdg graph computed", how can i access it?
is there any more documented thing about "impact" plugin than the official webpage, in depth, how it works fondamentally? (i have to say that i'm in like a pre-project phase, and that i installed frama-c with the apt-get on ubuntu and that i did not get an impact plugin working (i'll see by compiling the sources))
by the way, do you think i'm using the right method to get to my purposes?
Your question is quite unclear, and this answer is thus very generic. As mentioned in the developer documentation, there are two main classes of plugins: static plugins, compiled with the kernel and whose API is exposed in a module (usually of the same name of the plugin) in Db. Dynamic plugins, such as Semantic_callgraph register dynamically their entry points through the Dynamic module.
If you do make doc in Frama-C sources (I'm not sure that there is a corresponding package in Ubuntu) you can access documentation for the Db module in FRAMAC_SOURCE_DIR/doc/code/html/Db.html and the list of functions registered by dynamic plugins in FRAMAC_SOURCE_DIR/doc/code/dynamic_plugins/Dynamic_plugins.html.
I think that, following Virgile's advice, you should get the source code anyway because you will most of the time need to browse the code to find what you are looking for. Beside, you can have a look at the hello_word plug-in (in src/dummy/hello_world) to have an example of a very simple plug-in. You can also find some examples on my web site at https://anne.pacalet.fr/Notes/doku.php?id=notes:0061_frama_c_scripts to find out how to have access to some information in the AST.
I'm storing information in a custom property sheet for one of my custom products (I'm then using that information in a javascript file). I want this product to uninstall cleanly, but I can't seem to figure out how to remove a custom property sheet on uninstall using genericsetup. I know that remove="True" doesn't work, but I'm not having much luck figuring out the correct way (or any way for that matter) for removing this. Any suggestions would be greatly appreciated.
This is confusing for at least two reasons:
We have both "old style" and "new style" technologies actively in use. Old style refers to Extensions/Install.py (Python code) and new style refers to profiles/default (GS XML + setuphandlers.py Python code).
Successfully installing and uninstalling add-ons in all possible cases still requires the use of both old and new style technologies.
If you don't care about uninstall, you never need to use Extensions/Install.py. If you do care about uninstall, create an Extensions/Install.py with install and uninstall methods.
Also create an "uninstall" profile (in addition to the "default" profile) e.g. profiles/uninstall. Configure the Extensions/Install.py:install() method to execute your "normal" profiles/default steps on installation. Now comes the "fun" part.
Because some technologies can be uninstalled "properly" via GS i.e. they respect the remove=True parameter, your Extensions/Install.py:uninstall() method should execute the "proper" GS profiles to do the uninstall. But if your add-on uses technologies that cannot be uninstalled "properly" via GS i.e. those that do not respect the remove=True parameter, then you will need to write Python code to perform the uninstall.
See:
http://plone.org/documentation/kb/genericsetup/creating-an-uninstall-profile
for more information.