Hiding a specific object of a catalog results - plone

There is a way to hide a specific object of my catalog results?
I have a configuration file that I don't want to show.
I'm filtering by id, but it seems so ugly.
from Products.CMFCore.utils import getToolByName
def search(context):
catalog = getToolByName(context, 'portal_catalog')
items = catalog()
for item in items:
if item.id != "config_file":
'do something'

If you are already hiding the object from the navigation tree, you can filter on the same property by testing for exclude_from_nav:
items = catalog()
for item in items:
if item.exclude_from_nav:
continue
# do something with all objects *not* excluded from navigation.
It is harder to filter out things that don't match a criteria. Using a test on the brain object like the above is a perfectly fine way to remove a small subset from your result set.
If you need handle a larger percentage of 'exceptions' you'll need to rethink your architecture, perhaps.

With Products.AdvancedQuery you can create advanced queries and filtering on catalog results. See also this how to.

In the general case, setting a content item's expiration date to some past date hides it from search results (so long as the user does not have the Access inactive portal content permission).
It's an easy way to hide pieces of content that should be visible to all, but that you don't want cluttering up search results e.g. a Document that serves as the homepage.
I always use 1st Jan 2001 as the date so I can easily recognise when I've used this little 'hack'.

Related

How to use cursors for navigating to previous pages using GQL and the new gcloud-java API?

I'm using the new gcloud-java API (https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore) for working with the Cloud Datastore. My specific question is on using GQL for pagination with cursors. I was able to page through the results one page at a time in the forward direction using cursors, but not having any luck with paging backwards.
Example Scenario:
Let's say I've 20 entities in a Kind with IDs 1 through 20. I have a page size of 5. Once I'm on the 3rd page (IDs 11 through 15), if I need to go one page back; i.e. retrieve IDs 6 through 10, what would be the correct GQL/sample code? Again, I prefer not to use offset with a number, but would like to use Cursors.
From what I can tell (actually tested), it looks like one needs to keep track of Start/End cursors for each page as they navigate in the forward direction, then use the saved cursors when there is a need to go back. I just want to make sure if this is the correct/only way or there is a simpler way to accomplish this.
Thanks in advance for your help.
If you add to your original query a sort by key (appended to the end of your "order by" clause), you should be able to reverse each property's sort order and use the latest cursor from your original query to get results in reverse.
Suppose you've iterated through some of the values from your forward query's QueryResults. You can call QueryResults's cursorAfter() method, which will return a cursor pointing right after the last result you saw from your original query. Now you can issue a new query (with the opposite sort order on each property, including the key property) using that cursor as the start cursor. You'll probably want to skip the first result, since it will be the last result you saw from the original query.

Table input for view

I would like to have the user enter order items on my order form as a table where they input the Qty and Prod #. I've not programmed with that type of field so a blank line would initially display for a new order. They would type a Qty and an item number in the fields and hit enter. When they hit enter from either field, what do I program to check the validity of the two fields. Plus I need the item number to be a drop down/type ahead field. Does anyone have an example of this type of thing they could send me? It would be looking at a view in the product catalog db. Also, after they enter an item to order, that "doc" should get stored/saved and a new blank line should open up.
What type of control do I need to use and should these items be stored in their own form or on the main order document? Could use some guidance here. Thanks.
The question you have is a little broad but I will make a couple suggestions if I can.
You have the main order doc. Then a repeat control with each item. Filter each item by a uniqueID that allows you to join the main doc to the child docs. Each item should be a separate document. You then need to make the items in the repeat control editable.
There is a lot of things going on here and I think you need to get started somewhere. I think the first step is to do a repeat control with response documents.Xpages, Inherited documents in view panel by using #Unique

SmartGWT ListGrid FilterEditor getValue

I have a little appliation that shows MySQL data in web browser ListGrid. It has 14 columns.
I would like to upgrade it so the user could add query parameters.
For this job the best I could imagine is the grid.setShowFilterEditor() that put text boxes above the column headers and will live together with the column header when moved or resized.
I planned to use the filter button FilterEditorSubmitHandler() to get the filter values and run the query.
Unfortunately, I can not find any solution to get the text from a certain filter box eg. the value that was written by the user into the box above Column_#1. Is there any way to do that or this FilterEditor grown together with the DataSources object, and not available for any other data binding?
Something like this, but without using DataSource:
http://www.smartclient.com/smartgwt/showcase/#grid_sortfilter_disable_filter
As per my knowledge, filter editor works on com.smartgwt.client.data.DataSource only.
If you want to have filterEditor in ListGrid, you have to use DataSource or go for some custom implementation.

What does Managed="0" in List view XML mean?

I've written a Data Extender class and editor extension that properly displays a few additional columns for items as you browse lists in the CME (folders and structure groups). I had to register my class to handle commands like GetList, GetListSearch, GetListUserFavorites, and GetListCheckedOutItems.
What I've noticed is that the code gets run even when a list of say, schemas is loaded for a drop-down list in the CME (like when creating a new component and you get the list of schemas in a drop-down). so, even though my additional data columns aren't needed in that situation, the code is still being executed and it slows things down.
It seems that it's the GetList command called in those situations. So, I can't just skip processing based on the command. So, I started looking at the XML that the class receives for the list and I've noticed when the code is run for the drop-downs, there's a Managed="0" in the XML. For example:
For a Structure Group list: <tcm:ListItems Managed="64" ID="tcm:103-546-4">
For a Folder list: <tcm:ListItems Managed="16" ID="tcm:103-411-2">
But for a Schema list: <tcm:ListItems ID="tcm:0-103-1" Managed="0">
For a drop-down showing keyword values for a category: <tcm:ListItems Managed="0" ID="tcm:103-506-512">
So, can I just use this Managed="0" as a flag to indicate that the list being processed isn't going to show my additional columns and I can just quit processing?
Managed value is representation of what items can be created inside OrganizationItem:
64 means you can create pages
16 means you can create components
10, for example would mean you can create folders (2) + schemas (8)
518 - folders (2) + structure groups (4) + categories (512)
The value is 0 for non organizational items.
Value depends on the item itself (you can't create pages in folder, for example), as well as on security settings you have on publication and organizational item
Unfortunately CME can't offer right now that kind of granularity level to allow you to tell in a data extender where a particular WCF API call is coming from. Our WCF API is not context aware yet. It may change in the future.
Trusting Managed="0" is not a great idea.
The reason for that is the model lists are client cached per filter. In the current design the filter has CM related data and nothing related to the context the request is being fired from.
Typically the client user interface is reusing cached model data whenever is possible. For instance the same model list could be used in the CME dashboard and a drop down control placed into some item view, but with different xml list definitions: the first one will have more columns defined in the list definition than the latter. They are basically different views of the same data.
Therefore you may want to think of different solutions for your problem.
Now... where is the data behind those additional columns is coming from? Is it Tridion CM or a third party provider?
Sometimes the web server caching may provide an acceptable way to improve the response times. But that's the kind of design you should evaluate and decide upon.
I think you would have a more robust solution if you read the ID of the list, and only execute your code for lists of type 2 and 4 (Folders and Structure Groups respectively). but that won't help you with search views etc.
From previous experience and what User978511 says the Managed attribute is an indication of item types that can be created from the context of that list.
Unfortunately that means that the Managed attribute may well be 0 for any user that doesn't have sufficient rights to create items. E.g. check what Managed is in a Structure Group for a user that isn't allowed to create Pages or Structure Groups. It may well be 0 in that case too, meaning it is useless for your situation.
Update
You may be able to reach your goal better by looking at the columns parameter:
context.Parameters["columns"]
In a few tests I've run I get different values, depending on whether I get a list for the main list view, the tree or a drop down list.
543
23
7
Those values are a bit mask of these constants (from Constants.js):
/**
* Defines the column filter.
* Used to specify which attributes should be included in XML list data.
* #enum
*/
Tridion.Constants.ColumnFilter =
{
ID: 1,
ID_AND_TITLE: 3,
DEFAULT: 7,
EXTENDED: 15,
ALLOWED_ACTIONS: 16,
VERSIONS: 32,
INTERNALS: 64,
URL: 128,
XML_NAME: 256,
CHECK_OUT_USER: 512,
PUBTITLE_AND_ITEM_PATH: 1024
};
So from my limited testing it seems that drop downs request DEFAULT columns, while the main list view and the tree both have ALLOWED_ACTIONS in there. This makes sense to me, since the user gets can interact with the list items in the tree and list view, while they can only select them in the drop downs. So checking for the presence of ALLOWED_ACTIONS in the columns parameter might be one way to reduce the number of places where your data extender adds information.

Combine two views into one view

I have two views that I would like to combine into one.
The first view shows all items of X where company ID = Y. This is to give preferential sort to the client first, and then everyone else.
So I created a second view, all items of X, where company ID != Y.
I created it as an Attachment to attach to the first view, but I don't think I got the intended result.
How can I combine these views so the first view results are listed first, and then the second view is too, using the same pager, filters, and arguments?
Is there any way of achieving this without programming it?
From a MySQL point of view, the order-by-field syntax would be the appropriate way to handle this. Example:
SELECT * FROM tickets ORDER BY FIELD(priority, 'High', 'Normal', 'Low');
It would be great if there is a module that add this kind of functionality to Views, but AFAIK, it does not exist.
If you want to solve this without programming, I think you can use the rules module to automatically set the 'sticky' checkbox on nodes where company ID = Y. With that in place, you can order the View on the sticky value.
Along the lines of the 'sticky' idea, if you didn't want to override that, maybe you could add a checkbox field to the company type -- isClient. Make it false for everyone except the client, and sort by that.
I haven't done this, but maybe you need to create both versions as attachments, and attach them both to another display...?
for drupal 5 there was views union. Someone started something for D6, but I don't know how far they got.
http://drupal.org/node/275162
Create the second view as an attachment and attach it to first.
Set all Inherit arguments, Inherit exposed filters and Inherit pager to Yes.
how is the client parameter passed to the view? as an url argument? if so, you can create your second view like i outline here and then select the exclude the argument option on the appropriate location.
usually the easiest way to achieve this is with a small hook_query_alter, but that requires a small amount of programming.
A little bit later... but I've found a better solution using only the Views module:
Create a Block View with that shows the first list that you need ("all items of X where company ID = Y")
Create another View that must be a "Page view" with the second list (all items of X, where company ID != Y)
In the "HEADER" settings of this second view, click "Add" and select "Global: View area".
In the "View to insert" list, select the first you have created (and check "Inherid contextual filters" if you are using it)
And that's it!

Resources