Получите узлы контента на основе нескольких фильтров средства выбора контента umbraco 7

У меня есть тип документа с именем Career Item, который содержит некоторые свойства и 2 средства выбора контента. один для выбора типа карьеры: например. Водитель, другой — для выбора ветки, в которой будет размещена карьера: например. Гент Бельгия.

Типы и ветки My Career расположены в отдельных Content repository, это означает, что у них нет шаблона, это просто документ со свойствами, которые можно использовать на нескольких страницах контента.

Я создал для этого 2 фильтра, и с помощью jQuery мне удалось установить URL-адрес на основе выбора, чтобы получить такие URL-адреса:

http://localhost:59733/nl/vacatures/?f=1075&f=1076&b=1085&b=1082

Здесь у вас есть f, который содержит идентификаторы Career type, и b, который содержит идентификатор Branch.

Теперь в моей бритве я выполняю фильтрацию узлов контента на основе выбора, но это довольно запутано.

// Collect values for branch and function from the url querystring to perform filtering
var branch = umbraco.library.RequestQueryString("b"); // eg: 1085,1082 from example url above
var function = umbraco.library.RequestQueryString("f"); // eg: 1075,1076 from example url above

// Take the careers list content node
var careersList = Umbraco.TypedContentAtRoot().DescendantsOrSelf("CareersList").FirstOrDefault();
var careerItems = careersList.Children.Where("Visible");

string query = "";
string funcQuery = "";
string branchQuery = "";

// Filter on fuction
if (!String.IsNullOrEmpty(function))
{
    // Property alias function: content picker
    string[] functions = function.Split(',');
    foreach (string func in functions)
    {
        if (!String.IsNullOrEmpty(funcQuery))
        {
               funcQuery += " || function == \"" + func + "\"";
        }
        else
        {
               funcQuery = "function == \"" + func + "\"";
        }
    }
 }

  // Filter on branch
  if (!String.IsNullOrEmpty(branch))
  {
       // Property alias branch: content picker
       string[] branches = branch.Split(',');
       foreach (string br in branches)
       {
             if (!String.IsNullOrEmpty(branchQuery))
             {
                  branchQuery += " || branch == \"" + br + "\"";
             }
             else
             {
                  branchQuery = "branch == \"" + br + "\"";
             }
       }
 }

 funcQuery = !String.IsNullOrEmpty(funcQuery) ? "(" + funcQuery + ")" : "";
 branchQuery = !String.IsNullOrEmpty(branchQuery) ? "(" + branchQuery + ")" : "";

 query = funcQuery + (!String.IsNullOrEmpty(branchQuery) ? " && " + branchQuery : "");

 if (!String.IsNullOrEmpty(query))
 {
     careerItems = careerItems.Where(query);
 }

Я что-то упустил здесь, и можно ли это упростить? Потому что сейчас только 2 фильтра, а если у меня 5 или 6 фильтров, то это не сработает...

/Майкл


person Mivaweb    schedule 20.07.2015    source источник


Ответы (2)


Я также, возможно, подумал бы о том, чтобы поместить все это в метод расширения для IPublishedContent, называемый чем-то вроде CheckFilters, который принимает массивы в качестве параметров, поэтому вы можете сделать что-то вроде:

var branches = Request.QueryString("b").Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var functions= Request.QueryString("f").Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

var careerTypes = careersList.Where(a => a.IsVisible() && a.CheckFilters(branches, functions));

Вы можете иметь всю логику в методе расширения, а затем легко добавлять дополнительные фильтры, поскольку вы просто изменяете метод расширения или добавляете новые перегрузки.

Вам также не нужно использовать umbraco.library.RequestQueryString, так как это просто оболочка для функции Request.QueryString.

Вот очень грубый пример метода расширения:

public static bool CheckFilters(this IPublishedContent content, string[] branches, string[] functions)
{
    return branches.Contains(content.GetPropertyValue<string>("branchPropertyAlias", "")) && functions.Contains(content.GetPropertyValue<string>("functionPropertyAlias", ""));
}

Это довольно простой пример, в котором предполагается, что элемент контента имеет только одну ветвь и одну функцию.

person Tim    schedule 23.07.2015
comment
Где мне нужно добавить этот метод расширения? - person Mivaweb; 23.07.2015
comment
Либо в App_Code, либо в вашей DLL для сайта, если она у вас есть с пользовательскими функциями и т. д. Знаете ли вы, как писать методы расширения в С#? - person Tim; 23.07.2015
comment
Я делал это раньше, мне нужно будет освежить его, но я попробую и посмотрю. Если я застряну, я вернусь к вам. заранее спасибо - person Mivaweb; 23.07.2015
comment
Тим, не могли бы вы показать пример этого? Я создал статический класс, но теперь мне нужно создать статический метод для обработки этого. Кроме того, возможно ли разрешить этот метод расширения только для определенного псевдонима узла? Как в этом примере «CareersList»? - person Mivaweb; 24.07.2015
comment
Не уверен, как бы вы ограничили метод расширения только одним типом, но я исправлю свой ответ, включив в него пример метода расширения ....... - person Tim; 24.07.2015
comment
Неважно, я заработал, используя пример на форуме umbraco. Я хотел бы ограничить его одним псевдонимом, потому что не всем узлам нужен этот метод фильтрации. - person Mivaweb; 24.07.2015
comment
Ограничение метода расширения определенными типами узлов невозможно, так как расширение применяется к объекту независимо от свойств. Однако вы можете добавить некоторую логику в метод расширения, чтобы он выдавал ошибку, если вы попытаетесь вызвать его для неправильного типа узла или что-то подобное. - person Tim; 24.07.2015

Вы можете использовать что-то вроде этого:

var branch = "1085,1082";
var function = "1075,1076";

var careerTypes =
    careersList
        .Where(c => c.IsVisible() 
                    &&
                    branch.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                          .Select(i => int.Parse(i))
                          .Contains(c.GetPropertyValue<int>("branchId"))
                    &&
                    branch.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                          .Select(b => int.Parse(b))
                          .Contains(c.GetPropertyValue<int>("functionId"))
              );

//branchId and functionId are the property names of those 2 content pickers
person Davor Zlotrg    schedule 20.07.2015