tja
July 5, 2021, 2:33pm
1
I based my implementation on the article “Content from an RSS feed ”. However, I have problems to get all values of a XML file. I am currently trying to read out the values that are inside . The XML-file looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<item>
<hash>07548882287dc5asdasd2dbf741639abce</hash>
<ids label="IDs">
<system_id label="System ID">5874123</system_id>
</ids>
<publications locked="0">
<en>
<title>English Projecttitle</title>
<sample><![CDATA[<span style="color: #222222; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">Sample English</span>]]></sample>
<contacts>
<contact>
<type>
<id>3525</id>
<name>Print Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
</contacts>
</en>
<de>
<title>Deutscher Projekttitel</title>
<sample><![CDATA[<span style="color: #222222; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">Sample Deutsch</span>]]></sample>
<contacts>
<contact>
<type>
<id>3525</id>
<name>Print Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
</contacts>
</de>
</item>
</films>
The model like this
<?php
class MyRssfeedPage extends Page {
public function children()
{
$results = [];
$pages = [];
$request = Remote::get('sample.xml');
if ($request->code() === 200) {
$results = Xml::parse($request->content());
}
if (count($results) > 0) {
foreach ($results['item'] as $item) {
$pages[] = [
'slug' => Str::slug($item['hash']),
'template' => 'feeditem',
'model' => 'feeditem',
'content' => [
'title' => $item['publications']['de']['title'] ?? '',
'sample' => $item['publications']['de']['sample'] ?? '',
'contacts' => $item['publications']['de']['contacts'] ?? '',
]
];
}
}
return Pages::factory($pages, $this);
}
}
and the template like this:
<?php foreach ($page->children()->sortBy('date', 'desc') as $item): ?>
<?= $item->sample() ?>
DISPLAY CONTACT TEXT HERE
<?php endforeach ?>
Any hints on how to display the contact information would be appreciated.
What do you get when you dump($item->contacts())
?
I guess you just posted an extract from your xml file but it is invalid and therefore not suitable for testing the result.
tja
July 5, 2021, 3:44pm
3
I shortened the XML yes. The original file is much, much longer …
When I dump $item->contacts()
it looks something like this.
Kirby\Cms\Field Object
(
[contacts] => Array
(
[contact] => Array
(
[0] => Array
(
[type] => Array
(
[id] => 3525
[name] => Sample Name, City
)
[text] =>
)
)
)
)
The problem here is that you now have a field object with an array. You can either convert the field to an array with $item->contacts()->toArray()
.
Or you store the contacts array as yaml or json in your page model.
tja
July 5, 2021, 5:34pm
5
What do you think is the best way to do that? If I convert it to an array in the template as you suggested I still get the error “Array to string conversion
”. And if I do something like $listcontacts = Json::encode($item->contacts());
in the model then I get the error “Call to a member function contacts() on array
”.
I guess there is a lot that I am missing here?
Then you are probably trying to echo an array instead of getting the array values by there indices.
Where are you doing this? In the template?
tja
July 5, 2021, 6:30pm
7
I did it in the modal. When I place the code in the template I get the raw values of the Json data. I am not that used to working with Json. Do I have to loop over them in order to access the fields?
But in the model, you would have to json_encode your array:
'contacts' => json_encode($results['item']['publications']['de']['contacts'] ?? []),
Then you would json_decode the field value again in the template, which would again give you an array (or an object)
$contacts = json_decode($page->contacts()->value(), true);
But as I wrote above, you can directly work with the converted field array, you just cannot echo an array.
tja
July 6, 2021, 5:47pm
9
I tried my best to get it to run. Thank you very much for your suggestions! But unfortunately I failed so far. Here is my modal again.
<?php
class MyRssfeedPage extends Page {
public function children()
{
$results = [];
$pages = [];
$request = Remote::get('sample.xml');
if ($request->code() === 200) {
$results = Xml::parse($request->content());
}
if (count($results) > 0) {
foreach ($results['item'] as $item) {
$pages[] = [
'slug' => Str::slug($item['hash']),
'template' => 'feeditem',
'model' => 'feeditem',
'content' => [
'title' => $item['publications']['de']['title'] ?? '',
'sample' => $item['publications']['de']['sample'] ?? '',
'contacts' => json_encode($results['item']['publications']['de']['contacts'] ?? []),
]
];
}
}
return Pages::factory($pages, $this);
}
}
And here my template
<?php snippet('header') ?>
<main>
<header>
<h1><?= $page->title() ?></h1>
</header>
<div class="feed">
<?php foreach ($page->children()->sortBy('date', 'desc') as $item): ?>
<div style="margin-bottom:50px;">
<?= $item->sample() ?>
<?= $item->directors() ?>
<?php $contacts = json_decode($page->contacts()->value(), true); ?>
<?= var_dump($contacts)?>
</div>
<?php endforeach ?>
</div>
</main>
<?php snippet('footer') ?>
When I dump $contacts
I get NULL
. I tried converting it to an array in the template with $item->contacts()->toArray()
without luck. Again I got the Array to String conversion
error.
But because I initially shortened the XML-File I omitted some contact information. There are more than one contacts available. Could that be the reason for the errors? Here my a sample of the XML-File again:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<item>
<hash>07548882287dc5asdasd2dbf741639abce</hash>
<ids label="IDs">
<system_id label="System ID">5874123</system_id>
</ids>
<publications locked="0">
<en>
<title>English Projecttitle</title>
<sample><![CDATA[<span style="color: #222222; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">Sample English</span>]]></sample>
<contacts>
<contact>
<type>
<id>3525</id>
<name>Print Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
<contact>
<type>
<id>3526</id>
<name>Sample Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
</contacts>
</en>
<de>
<title>Deutscher Projekttitel</title>
<sample><![CDATA[<span style="color: #222222; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">Sample Deutsch</span>]]></sample>
<contacts>
<contact>
<type>
<id>3525</id>
<name>Print Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
<contact>
<type>
<id>3526</id>
<name>Sample Owner</name>
</type>
<text><![CDATA[Sample Name, City]]></text>
</contact>
</contacts>
</de>
</item>
</project>
The resulting structure is a bit unexpected. If you change the current setup in your model to this:
'contacts' => json_encode($results['item']['publications']['de']['contacts']['contact'] ?? []),
then you can do it like this:
<?php foreach ($page->children()->sortBy('date', 'desc') as $item): ?>
<?php $contacts = json_decode($item->contacts()->value(), true) ?>
<?php foreach ($contacts as $contact):?>
<?php echo $contact['text'] ?>
<?php echo $contact['type']['id'] ?>
<?php endforeach ?>
<?php endforeach ?>
tja
July 8, 2021, 6:33am
11
Unfortunately, I cannot read out any values this way. But I can with the following code (in the template).
<?php
$results = [];
$pages = [];
$results = simplexml_load_file('sample.xml');
?>
<?php foreach ($results as $item): ?>
<?php if (isset($item->publications->de->contacts)): ?>
<?php foreach ($item->publications->de->contacts as $contact):?>
<?php foreach ($contact as $i):?>
<?= $i->text ?><br>
<?= $i->type->id ?><br>
<?php endforeach ?>
<?php endforeach ?>
<?php endif ?>
<?php endforeach ?>
I have not yet managed to reproduce this in the model. But many thanks for your help. I appreciate it.
tja
July 8, 2021, 7:09pm
12
Allright. I managed to get it to run with this model
<?php
class FeedPage extends Page {
public function children()
{
$results = [];
$pages = [];
$request = Remote::get('sample.xml');
if ($request->code() === 200) {
$results = Xml::parse($request->content());
}
if (count($results) > 0) {
foreach ($results['item'] as $item) {
$pages[] = [
'slug' => Str::slug($item['hash']),
'template' => 'feeditem',
'model' => 'feeditem',
'content' => [
'title' => $item['publications']['de']['title'] ?? '',
'contacts' => $item['publications']['de']['contacts'] ?? '',
]
];
}
}
return Pages::factory($pages, $this);
}
}
and this code inside the template
<?php foreach ($page->children()->sortBy('date', 'desc') as $item): ?>
<?php $contacts = $item->contacts() ?>
<?php if (isset($contacts)): ?>
<?php foreach ($contacts as $contact):?>
<?php if (is_array($contact)==1):?>
<?php foreach ($contact["contact"] as $j):?>
<?= $j["type"]["id"] ?><br>
<?= $j["text"] ?><br>
<?php endforeach?>
<?php endif?>
<?php endforeach ?>
<?php endif ?>
<?php endforeach ?>