CategoryManyToManyField tuns to emty QuerySet in non edit mode - django-cms

I write a new plugin for aldryn_newsblog application. I want to list articles by categories. The plugin takes the list of categories using CategoryManyToManyField.
The plugin displays the articles having requested categories only in edit mode. As soon as I publish page with newly added plugin it displays none of the articles. I checked that self.categories.all() becomes empty.
Why it is happening?
This is for;
aldryn-newsblog2.1.1
Django==1.11.17
django-cms==3.5.3
It acts the same on local django development server and on remote apache
class NewsBlogCategoryPlugin(PluginEditModeMixin, AdjustableCacheModelMixin, NewsBlogCMSPlugin):
....
categories = CategoryManyToManyField('aldryn_categories.Category', verbose_name=_('categories'), blank=True)
....
def get_articles(self, request):
print (self.categories.all())
queryset = Article.objects
main_qs = queryset.all().filter(categories =
self.categories.all())
return main_qs

I believe that the issue is this:
when your page is published, the plugin instance is copied
in the published version of the page, there is now a new plugin instance
this new plugin instance does not have the relations to the Categories that the original did
You need to ensure that when a plugin is copied, so are its relations.
See handling relations in the django CMS documentation.

Thank you #Daniele. I just have added following the handling-relations
def copy_relations(self, oldinstance):
self.categories = oldinstance.categories.all()
And now it works

Related

DjangoCMS: How to check for uniqueness of a field in a plugin model (CMSPlugin)?

I build a djangoCMS plugin which contain a slug. I want this slug to be unique.
Since djangoCMS store page content in draft and public versions (with a copy of plugins data), I can't do it at database level because it is normal two have at two plugins (draft and public versions) with the same slug.
I'm pretty sure there is an idiom for this but can't find it.
I've tried to make a check in the clean method of the model, but I can't access instance.placeholder which is None when being in clean method…
class MyPlugin(CMSPlugin):
slug = models.SlugField(
verbose_name=_("Slug"),
db_index=True,
max_length=255,
)
Any idea ?
I think I've found a solution by excluding objects where page is not draft:
def clean(self, *args, **kwargs):
sames_slug = MyPlugin.objects.filter(slug=self.slug).exclude(
placeholder__page__publisher_is_draft=False
)
if self.pk:
sames_slug = sames_slug.exclude(pk=self.pk)
if sames_slug.exists():
raise ValidationError(
{"slug": "There is already one with the same slug"}
)

how to add node in through Drupal API

In order to insert an article to Drupal there are thee ways of doing that:
by admin panel - really slow and not feasable if talking about 400 articles
by pure sql - number of tables that have to maintained and calculated (content, core, cat etc.) is quite high and it's not really reliable
by using drupal API - that's something that I was trying to implement but can't find a good documentation on it. What I'm trying to achieve is to use drupal classes and insert content (ie. running a PHP file with (catid,title,introtext....))
Example: what i want to add node in xyz.com/drupal site but my php code should be run in irankmedi.com
Can you please point me into direction where I can find some info on how to manage articles and categories this way?
Thanks in advance
If your request is very specific and you can't find a module that does what you need it shouldn't be too difficult to make a module on your own and import (create drupal) content from your code. Should be something like this:
Create a php file that will do the job.
At start of your script include standard Drupal's bootstrap code so you'll have all Drupal's functionality available in your script
Make code that will read content (from database or feed or something else).
Use Drupal api to insert node programatically:
https://www.drupal.org/node/1388922
Call your script manually or set cron to call it on specific time periods.
First you have to read RSS feed in drupal custom module. Then, following code can create node programatically.
$node = new stdClass();
$node->type = 'blog'; // This type should exist
node_object_prepare($node); // Sets some defaults.
$node->language = LANGUAGE_NONE; // The language of the default
$node->title = "testnode";
$node->body[LANGUAGE_NONE][0]['value'] = "Body";
node_save($node); // function that actually saves node in database

Getting the site name in alfresco email notification

I am trying to notify users whenever a site is created in alfresco share. I created a rule for the site folder in the repository.
In Define Rule, I selected:
When: Items are created or entered in the folder
If all criteria are met: Description contains "a"
Perform Action: Send email
But in the message of the email I need to give the site name.
For example:
A new site named "Sample" is created. Click the link to join the site.
How can I get the site name and corresponding link to join the site?
You can do something like this.
var currentSite = Alfresco.constants.SITE;
var siteObject = siteService.getSite(currentSite );
If you are using javascript directly to send mail you you will have site object available .
You can also try this
siteId = page.url.templateArgs.site;
If you are using ftl you can probably pass sitename from script file to FTL file.
You have multiple options to get current site name depending on the context where you are trying to access it.

Some functions don't work when using two databases in Wordpress

I'm working on migrating one WP site to a new one. Both are rather advanced with many custom fields, taxonomies and post types so I can't use the built in plugins for importing/exporting.
Instead I've set up both databases on the same server and can easily switch between them using $wpdb->select('old_db_name') and $wpdb->select(DB_NAME). I've created a tiny plugin for this so that it runs from inside WP and thus allows me to use all the WP-methods for fetching and inserting posts etc.
Everything works fine except for one thing; taxonomies. All the functions I've tried that are related to taxonomies will query the DB_NAME database (i.e. the one the WP installation is running from).
Here's a simple example:
<?php
global $wpdb;
# Use default DB
$wpdb->select(DB_NAME);
# Prints "2" (I've only added two posts to the new installation)
echo count(get_posts(array('numberposts' => -1)));
# Prints all the taxonomies
var_dump(get_taxonomies());
# Switch to old DB
$wpdb->select('old_db_name');
# Prints > "300" (there are roughly 300 posts in the old DB - the number is correct and NOT the same as before)
echo count(get_posts(array('numberposts' => -1)));
# Prints EXACTLY the same thing as the previous call, even though the old DB has different custom taxonomies
var_dump(get_taxonomies());
wp_get_post_terms() doesn't work either but instead queries the new DB (if I try to fetch the terms from an old taxonomy that no longer exists in the new DB WP throws an error saying that the taxonomy doesn't exist).
Is this a bug? Any way to solve it? There's not much info about using more than one DB in WP so haven't been able to find anything online.
Ok so after hours of investigation it seems that WP caches all the available taxonomies on initialization, so when switching DB it will not re-check available taxonomies. It does however select data from the correct DB so that was not the issue.
The solution I came up with was simply adding the missing taxonomies to the new DB (temporarily), and after the migration I'll just remove them.

Tridion 2009 - Publish another Component from a Component Template

First, the overall description:
There are two Component Templates, NewsArticle and NewsList. NewsArticle is a Dreamweaver Template, and is used to display the content of a news article. NewsList is an xml file that contains aggregated information about all of the news articles.
Currently, a content author must publish the news article, and then re-publish the newslist to regenerate the xml.
Problem:
I have been tasked with having the publish of a news article also regenerate and publish the newslist. Through C#, I am able to retrieve the content of the newslist component, generate the updated xml from the news article, and merge it into the xml from the newslist. I am running into trouble getting the newslist to publish.
I have limited access to documentation, but from what I do have, I believe using the static PublishEngine.Publish method will allow me to do what I need. I believe the first parameter (items) is just a list that contains my updated newslist, and the second parameter is a new PublishInstruction with the RenderInstruction.RenderMode set to Publish. I am a little lost on what the publicationTargets should be.
Am I on the right track? If so, any help with the Publish method call is appreciated, and if not, any suggestions?
Like Quirijn suggested, a broker query is the cleanest approach.
In a situation if a broker isn't available (i.e. static publishing model only) I usually generate the newslist XML from a TBB that adds the XML as a binary, rather than kicking off publishing of another component or page. You can do this by calling this method in your C# TBB:
engine.PublishingContext.RenderedItem.AddBinary(
Stream yourXmlContentConvertedToMemoryStream,
string filename,
StructureGroup location,
string variantId,
string mimeType)
Make the variantId unique per the newslist XML file that you create, so that different components can overwrite/update the same file.
Better yet, do this in a Page Template rather than Component Template so that the news list is generated once per page, rather than per component (if you have multiple articles per page).
You are on the right tracks here with the engine.Publish() method:
PublishEngine.Publish(
new IdentifiableObject[] { linkedComponent },
engine.PublishingContext.PublishInstruction,
new List() { engine.PublishingContext.PublicationTarget });
You can just reuse the PublishInstruction and Target from the current context of your template. This sample shows a Component, but it should work in a page too.
One thing to keep in mind is that this is not possible in SDL Tridion 2011 SP1, as the publish action is not allowed out of the box due to security restrictions. I have an article about this here http://www.tridiondeveloper.com/the-story-of-sdl-tridion-2011-custom-resolver-and-the-allowwriteoperationsintemplates-attribute

Resources