Продолжаем разбираться с XML-RPC в WordPress. На данный момент в блоге можно получить информацию по использованию XML-RPC для чтенния комментариев и заголовков постов блога. Сегодня будем определять не только названия постов, но и их адреса в блоге, а также всю информацию о статье в блоге. Использовать полученную информацию можно будет где угодно, например, для создания своих блог-клиентов или для автосабмитта в теже сервисы соц.закладок.
Вариант 1 — в лоб.
Как я уже отмечал ранее, WordPress помимо своего API поддерживает также и ряд других иснтерфейсов, таких как Blogger API, MetaWeblog API и MovableType API. Видимо по причине такой широкой поддержки API сторонних производителей, разработчики WordPress не стали разрабатывать самостоятельно методы для доступа к отдельных постам блога в WordPress API, что вполне логично, т.к. методов хватает. И первый метод, которым мы можем воспользоваться — это metaWeblog.getRecentPosts. Согласно спецификаци этот метод возвращает всю информацию по постам блога и для того, чтобы воспользоваться методом необходимо передать следующие параметры:
- blogid — id блога (равен 1)
- username — имя пользователя (администратора) блога
- password — пароль
- numberOfPosts — количество постов
Если numberOfPosts равен 1, то вернется информация по последнему опубликованному посту, если 2 по последниму и предыдущему и т.д. Если же numberOfPosts будет больше, чем количество постов в блоге, то вернется массив структур, каждая из которых — отдельный пост блога.
Попробуем воспользоваться методом для получения URL постов блога. Пока обойдемся без разбора XML, т.е. получим ответ и сохраним его на диске:
function TWordPress.GetPostStructure: IXMLDocument; var aDoc: IXMLDocument; Root:IXMLNode; begin aDoc:=NewXMLDocument(); aDoc.Active:=true; Root:=aDoc.AddChild('methodCall'); Root:=aDoc.DocumentElement.AddChild('methodName'); Root.Text:='metaWeblog.getRecentPosts'; Root:=aDoc.DocumentElement.AddChild('params'); SetParam(tsInt, '1',aDoc); SetParam(tsString, Login,aDoc); SetParam(tsString, Password,aDoc); SetParam(tsInt,IntToStr(high(integer)),aDoc); with THTTPSend.Create do begin aDoc.SaveToStream(Document); HTTPMethod('POST',FRPCPoint); Result:=NewXMLDocument(); Result.LoadFromStream(Document); Document.SaveToFile('posts.xml'); end; end;
Если выполнить эту функцию, то в файл будет записана информация по всем имеющимся в блоге постам, в т.ч. и информация по ключевым свловам и мета-тегам (если установлены соответствующие плагины).
У меня в результате получился файл на 3,2 Mb. Следовательно, при низкой скорости соединения ждать выполнения такой функции придётся весьма долго. Поэтому попробуем выработать другое решение.
Вариант 2 — получаем информацию по каждому посту в отдельности.
Как можно добитьмя меньшего потребления ресурсов при работе с постами в блоге? К сожалению в API, предоставляемых в наше распоряжение WordPress нет отдельным методов на получение, например, информации по посту, которая не будет включать в себя текстовую часть, а будут возвращать только ссылки на пост. Поэтому более менее приемлимый вариант для работы с постами может выглядеть таким образом:
- Используем метод mt.getRecentPostTitles из MovableType API и получаем заголовок поста, дату создания и id для поста. Т.к. количество информации, возвращаемой этим методом, на порядок меньше, чем при использовании metaWeblog.getRecentPosts, то соответственно метод сработает намного быстрее и «легче».
- Используя идентификатор поста (id) запрашиваем информацию по каждому посту в отдельности, используя для этого один из следующих методов: metaWeblog.getPost, blogger.getPost.
Таким образом нам не придётся ждать по полчаса пока закачается документ в N Мб, а можем в цикле обрабатывать каждый пост в отдельности и, при необходимости, без проблем прервать выполнение работы и продолжить её с места остановки.
Попробуем реализовать все вышесказанное в виде программного кода. Для начала договговримся, что будем хранить. Путь это будут название поста, его id и ссылка (URL). Объявляем следующий тип данных:
type
TPostStruct = packed record id: string; title: string; url: string; end;
и одну переменную:
FPostList: array of TPostStruct;
Первый метод будет получать информацию о заголовках и id постов и сохранять эти данные в список:
function GetPostStructure: IXMLDocument; var aDoc: IXMLDocument; Root:IXMLNode; Values,Members: IDOMNodeList; i,j:integer; Struct:TPostStruct; begin aDoc:=NewXMLDocument(); aDoc.Active:=true; Root:=aDoc.AddChild('methodCall'); Root:=aDoc.DocumentElement.AddChild('methodName'); Root.Text:='mt.getRecentPostTitles'; Root:=aDoc.DocumentElement.AddChild('params'); SetParam(tsInt, '1',aDoc); SetParam(tsString, FLogin,aDoc); SetParam(tsString, FPassword,aDoc); SetParam(tsInt,IntToStr(high(integer)),aDoc); with THTTPSend.Create do begin aDoc.SaveToStream(Document); HTTPMethod('POST',FRPCPoint); Result:=NewXMLDocument(); Result.LoadFromStream(Document); Document.SaveToFile('posts.xml'); aDoc.LoadFromStream(Document); Values:=aDoc.DOMDocument.getElementsByTagName('data').item[0].childNodes; for i:= 0 to Values.length-1 do begin Members:=Values[i].firstChild.ChildNodes;//получили все members для 1 value SetLength(FPostList, length(FPostList)+1); for j:=2 to Members.length-1 do begin FPostList[length(FPostList)-1].id:=(Members[2].lastChild.firstChild as IDOMNodeEx).text; FPostList[length(FPostList)-1].title:=(Members[3].lastChild.firstChild as IDOMNodeEx).text; end; PostList.Add(Struct); end; end; end;
Теперь остается пройтись по всем элементам в PostList и получить URL’ы постов. Сначала научимся получать URL отдельного поста:
function RetriveURL(const post_id: string): string; var aDoc: IXMLDocument; Root:IXMLNode; begin aDoc:=NewXMLDocument(); aDoc.Active:=true; Root:=aDoc.AddChild('methodCall'); Root:=aDoc.DocumentElement.AddChild('methodName'); Root.Text:='metaWeblog.getPost'; Root:=aDoc.DocumentElement.AddChild('params'); SetParam(tsString, post_id ,aDoc); SetParam(tsString, FLogin,aDoc); SetParam(tsString, FPassword,aDoc); {отправляем запрос и ждем ответ} with THTTPSend.Create do begin aDoc.SaveToStream(Document); if HTTPMethod('POST',FRPCPoint)then begin aDoc:=NewXMLDocument(); aDoc.LoadFromStream(Document); {добираемся до узлов member структуры} {для примера рассматриваем каждый шаг} Root:=aDoc.DocumentElement.ChildNodes.First;//узел params Root:=Root.ChildNodes.First;//узел param Root:=Root.ChildNodes.First;//узел value Root:=Root.ChildNodes.First;//узел struct //шестой элемен member - ссылка (Link) //второй дочерний эемент - значение элемента Result:=Root.ChildNodes[5].ChildNodes[1].ChildNodes[0].Text; end else exit; end; end;
И теперь можно пробежаться по всему массивы и полностью заполнить даанные по постам блога:
procedure TWordPress.RetriveAllURL; var i:integer; begin for I := 0 to FPostList.Count - 1 do FPostList[0].url:=RetriveURL(FPostList[i].id) end;
Используя метод RetriveURL можно, как и в Варианте 1, получить всю информацию по посту, включая автора, HTML-код поста, ключевые слова и т.д.