I have an Akeneo 2.3 running with 10 locales. 1 of the locales is our customised one called ab_AB.
When viewing the category tree in Settings -> Categories UI or when assigning product to categories UI, the category's label is displayed according to the locale of the logged-in user.
I would like to display the category's label value from ab_AB locale instead of the logged-in user's locale.
I have looked into /vendor/akeneo/pim-community-dev/src/Pim/Bundle/EnrichBundle/Resources/views/CategoryTree for hints of what to extend/override but not quite sure what to make of it.
To sum up what happens: the tree is generated by calling CategoryTreeController::childrenAction. The rendered twig view will format the categories using the Twig function children_response, defined in the CategoryExtension.
To set your own locale, you need to override this extension in your project (extend the class and redefine the class parameter pim_enrich.twig.category_extension.class) and override the protected method getLabel as follows:
protected function getLabel(
CategoryInterface $category,
$withCount = false,
$includeSub = false,
$relatedEntity = 'product'
) {
$category->setLocale('ab_AB');
return parent::getLabel($category, $withCount, $includeSub, $relatedEntity);
}
I successfully tested it with locale fr_FR while my PIM was in English. Category labels were then in French, both in the Settings → Categories menu and the category filter of the product grid.
Related
Is it possible to translate a non snipppet/page model in Wagtail >= 2.11 and wagtail-localize >= 0.9.3 ?
I've set up my model as follows:
class TrainingPlace(TranslatableMixin, models.Model):
name = models.CharField()
description = models.TextField()
class Meta(TranslatableMixin.Meta):
verbose_name = "Training Places"
translatable_fields = [
TranslatableField("description")
]
I have a "Training" submenu in my wagtail admin page, with Trainings, Training Photos, Trainers, Training Places, where I can add Trainers, new Trainings etc.
If I register a TraningPlace with a #register_snipppet I can translate it, but at the moment there are some problems:
I see many Trainings (menu) -> TrainingPlace recoreds in admin listing with no "Translate" option
If I go to Snippets (menu) => Training Place snippets I can see snipppets and have option to translate/create/sync translations, but when I click on change language button in admin I am getting a blank page (url points to a snippet with different ID) which may be a bug.
Can non snippet/page models be translated in admin when using TranslatableMixin on model ?
I have a wagtail installation using the Multisite pattern, where I have a group of user per site and each group as it's own collection.
When the User logged in the admin interface, they see in the Summary section the image count from all the collections.
But when they click the image menu, they only see the images within their group collection. I found it confusing that they could know the total count of all collections. I wanted to get the count from the collection the user had rights for.
I figured out I could override the ImagesSummaryItem and I ended up coding the following snippet of code:
class CorrectedImagesSummaryItem(SummaryItem):
order = 200
template = 'wagtailimages/homepage/site_summary_images.html'
def get_context(self):
site_name = get_site_for_user(self.request.user)['site_name']
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=['change_image', 'add_image'])
collections = Collection.objects.filter(
group_permissions__group__in=self.request.user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
if collections:
image_count = get_image_model().objects.filter(collection__in=collections).count()
else:
image_count = 0
return {
'total_images': image_count,
'site_name': site_name,
}
def is_shown(self):
return permission_policy.user_has_any_permission(
self.request.user, ['change', 'add']
)
#hooks.register('construct_homepage_summary_items')
def add_corrected_images_summary_panel(request, items):
"""Replaces the Images summary panel to hide variants."""
for index, item in enumerate(items):
if item.__class__ is ImagesSummaryItem:
items[index] = CorrectedImagesSummaryItem(request)
This actually works fine, I am now showing the proper images count on the summary section but I am wondering is there a better way to query the collections of the user? Are these querysets right?
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=['change_image', 'add_image'])
collections = Collection.objects.filter(
group_permissions__group__in=self.request.user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
Update
I ended up customizing the queryset for the images selection in order to only show the images within the collection the user was having access to.
In addition of the first function, I added the following code in my wagtail_hooks.py file.
#hooks.register('construct_image_chooser_queryset')
def show_collection_images_only(images, request):
# Show only the images from the collection the User has access.
collections = get_collections_from_group_permissions(request.user, ['change_image', 'add_image'])
images = images.filter(collection__in=collections)
return images
The get_collections_from_group_permissions is just a simplified function that returns exactly the Collection out of the Groups permissions the User has.
def get_collections_from_group_permissions(user, permissions):
"""
This function gets the Collections from the user groups permissions.
:param user: the user
:param permissions: the requested permissions on a Collection object
:returns: the Collections the selected User has access rights for.
"""
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=permissions)
collections = Collection.objects.filter(
group_permissions__group__in=user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
return collections
With this in place, the Summary Item for the images is the number of images within the collections the User can access and when he clicks on a ImageChooserField and gets to the Image chooser, he only gets to see what is in the collections he has been granted access.
This logic is already implemented in Wagtail's permission_policy class, so this could be reduced to:
image_count = permission_policy.instances_user_has_any_permission_for(
self.request.user, ['change', 'add']
).count()
(Incidentally, the reason Wagtail itself doesn't take permissions into account when displaying this figure is that all users can see the complete set of images via the chooser popup - there's currently no 'choose' permission - so showing a reduced number would be misleading. See the discussion at https://github.com/wagtail/wagtail/issues/5129)
I want to write a request on the search result request webpart. My request should enables me to retrieve all documents that have the biggest number of likes. There is no variable for the number of likes proposed on the drop list while writing a request , that why I decided to set a refinableInt00 variable and give it the value : LikesCount but it doesn't work? it means that LikesCount doesn't exist as a variable on sharepoint so what is the variable on sharepoint that would enable me to have the number of likes?
You can get the number of likes using the listitem property "Number of Likes"
This is a code from a Sample console application
using (SPSite site=new SPSite("your site URL"))
{
using (SPWeb web=site.OpenWeb())
{
SPList list = web.Lists["Your List Name"];
foreach (SPListItem item in list.Items)
{
//Print the number of likes
Console.WriteLine(item["Number of Likes"].ToString());
}
}
}
I know this is old but I had the same question. The problem is the LikesCount property does not default to Sortable. To fix this:
-Open up Central Administration
-Go to Search Service Application
-Click on Search Schema
-Locate the "LikesCount" property and click edit
-Scroll down to Sortable and change to Yes
-Run a full crawl on your content source
Ratings for list must be enable.
List -> List settings -> Rating settings ->
Allow items in this list to be rated?
yes ? no
and
Which voting/rating experience you would like to enable for this list?
Likes ? Star Ratings
After that you can access likes by "Number of Likes" field name "LikesCount".
"Number of Ratings" field name "RatingCount"
I have add custom field to Account with picklist(multiple) in Salesforce. But the values of picklist should be dynamically generated from other object. If not, is it possible to push values in picklist from native app(which is written in ruby)?
I dont think the standard controller supports dynamically adding the possible picklist (select list) values.
What you could do is add a text field instead of a picklist and create a custom page with visualforce. Use the standard controller with an extension for your code.
Create a new custom object for holding picklist values for a field (could be reused for other fields). Populate it with the possible picklist values.
In the page controller, load the values for that field.
In visualforce, display a picklist for the custom field and load the values from the controller.
Add an extra input field for manual insertion if desired.
On save, insert the value of the picklist (or input box) into the custom field.
A more detailed guide can be found here
Why dont't you use a normal SelectOption List in Apex?
public List<SelectOption> getMyPicklist()
{
List<SelectOption> options = new List<SelectOption>();
List<Account> acc = [ Select Id, Name From Account Limit 10 ];
for(Account a : acc){
options.add(new SelectOption(a.Id,a.Name));
}
return options;
}
I had to update picklist with values from my database (and not from some visualforce page). So I authenticated account using Databasedotcom gem and it provides nice Api to iteract with Salesforce Objects (both Standard and Custom).
client.authenticate :token => "my-oauth-token", :instance_url => "http://na1.salesforce.com" #=> "my-oauth-token"
account = client.materialize("Account")
account_to_be_updated = account.find(account_id) # here account is same as Instance of Activerecord
account_to_be_updated.my_picklist = [value1; value2; value3; value4]
account_to_be_updated.save
My app has sales listing functionality that will allow the user to add 1 or more photos for the product that they want to sell.
I'm attempting to use the upload/filestore_image of ATK with a Join table to create the relationship - my models:
class Model_Listing extends Model_Table {
public $entity_code='listing';
function init(){
parent::init();
$this->addField('name');
$this->addField('body')->type('text');
$this->addField('status');
$this->addField('showStatus')->calculated(true);
}
function calculate_showStatus(){
return ($this->status == 1) ? "Sold" : "For Sale" ;
}
}
class Model_listingimages extends Model_Table {
public $entity_code='listing_images';
function init(){
parent::init();
$this->addField('listing_id')->refModel('Model_Listing');
$this->addField('filestore_image_id')->refModel('Model_Filestore_Image');
}
}
In my page manager class I have added the file upload to the crud:
class page_manager extends Page {
function init(){
parent::init();
$tabs=$this->add('Tabs');
$s = $tabs->addTab('Sales')->add('CRUD');
$s->setModel('Listing',array('name','body','status'),array('name','status'));
if ($s->form) {
$f = $s->form;
$f->addField('upload','Add Photos')->setModel('Filestore_Image');
$f->add('FileGrid')->setModel('Filestore_Image');
}
}
}
My questions:
I am getting a "Unable to include FileGrid.php" error - I want the user to be able to see the images that they have uploaded and hoped that this would be the best way to do so - by adding the file grid to bottom of the form. - EDIT - ignore this question, I created a FileGrid class based on the code in the example link below - that fixed the issue.
How do I make the association between the CRUD form so that a submit will save the uploaded files and create entries in the join table?
I have installed the latest release of ATK4, added the 4 filestore tables to the db and referenced the following page in the documentation http://codepad.agiletoolkit.org/image
TIA
PG
By creating model based on Filestore_File
You need to specify a proper model. By proper I mean:
It must be extending Model_Filestore_File
It must have MasterField set to link it with your entry
In this case, however you must know the referenced ID when the images are being uploaded, so it won't work if you upload image before creating record. Just to give you idea the code would look
$mymodel=$this->add('Model_listingimages');
$mymodel->setMasterField('listing_id',$listing_id);
$upload_field->setModel($mymodel);
$upload_field->allowMultiple();
This way all the images uploaded through the field will automatically be associated with your listing. You will need to inherit model from Model_Filestore_File. The Model_Filestore_Image is a really great example which you can use. You should add related entity (join) and define fields in that table.
There is other way too:
By doing some extra work in linking images
When form is submitted, you can retrieve list of file IDs by simply getting them.
$form->get('add_photos')
Inside form submission handler you can perform some manual insertion into listingimages.
$form->onSubmit(function($form) uses($listing_id){
$photos = explode(',',$form->get('add_photos'));
$m=$form->add('Model_listingimages');
foreach($photos as $photo_id){
$m->unloadDdata()->set('listing_id',$listing_id)
->set('filestore_image_id',$photo_id)->update();
}
}); // I'm not sure if this will be called by CRUD, which has
// it's own form submit handler, but give it a try.
You must be careful, through, if you use global model inside the upload field without restrictions, then user can access or delete images uploaded by other users. If you use file model with MVCGrid you should see what files they can theoretically get access to. That's normal and that's why I recommend using the first method described above.
NOTE: you should not use spaces in file name, 2nd argument to addField, it breaks javascript.