Last active
August 14, 2023 06:04
-
-
Save texnixe/637b4096032a722370696d5d750b9918 to your computer and use it in GitHub Desktop.
Collection of custom Kirby page, pages, field etc. methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// page methods | |
// check if page has Parents | |
page::$methods['hasParents'] = function($page) { | |
return $page->parents()->count(); | |
}; | |
// get max nesting level of page | |
page::$methods['maxDepth'] = function($page) { | |
foreach($page->index() as $p) { | |
$depth[] = $p->depth(); | |
} | |
return max($depth); | |
}; | |
// get index of page in collection | |
page::$methods['getIndex'] = function($page, $collection) { | |
$index = $collection->indexOf($page); | |
return $index; | |
}; | |
// get next page of a given children collection (e.g. filtered collection) | |
page::$methods['getNext'] = function($page, Children $siblings, $sort = array(), $visibility = false) { | |
if($sort) $siblings = call(array($siblings, 'sortBy'), $sort); | |
$index = $siblings->indexOf($page); | |
if($index === false) return null; | |
if($visibility) { | |
$siblings = $siblings->offset($index+1); | |
$siblings = $siblings->{$visibility}(); | |
return $siblings->first(); | |
} else { | |
return $siblings->nth($index + 1); | |
} | |
}; | |
// get prev page of a given children collection (e.g. filtered collection) | |
page::$methods['getPrev'] = function($page, Children $siblings, $sort = array(), $visibility = false) { | |
if($sort) $siblings = call(array($siblings, 'sortBy'), $sort); | |
$index = $siblings->indexOf($page); | |
if($index === false or $index === 0) return null; | |
if($visibility) { | |
$siblings = $siblings->limit($index); | |
$siblings = $siblings->{$visibility}(); | |
return $siblings->last(); | |
} else { | |
return $siblings->nth($index - 1); | |
} | |
}; | |
page::$methods['getContent'] = function($page, $field) { | |
if($page->$field()->exists() && $page->$field()->isNotEmpty()) { | |
return $page->$field()->kt(); | |
} else { | |
foreach($page->parents() as $page) { | |
if($page->$field()->isNotEmpty()) { | |
return $page->$field()->kt(); | |
exit; | |
} | |
} | |
} | |
}; | |
// $page->getImage('coverimage', 'cover') | |
page::$methods['getImage'] = function($page, $field, $class='') { | |
$image = $page->$field()->toFile(); | |
if($image) { | |
$img = new Brick('img'); | |
$img->attr('src', $image->url()); | |
$img->attr('alt', $image->alt()); | |
$figure = new Brick('figure'); | |
$figure->addClass($class); | |
$figure->append($image); | |
return $figure; | |
} else { | |
return ''; | |
} | |
}; | |
//method to create a custom url | |
page::$methods['customeUrl'] = function($page) { | |
return site()->url() . '/something/' . $page->uid(); | |
}; | |
page::$methods['canonicalURL'] = function($page) { | |
return $page->url() . r(params(), '/') . kirby()->request()->params(); | |
}; | |
page::$methods['canonicalURL'] = function($page) { | |
return $page->url() . r(params() || $page->isHomePage(), '/') . kirby()->request()->params(); | |
}; | |
// pages methods | |
pages::$methods['onlyTranslated'] = function($pages) { | |
return $pages->filter(function($page) { | |
return $page->content(site()->language()->code())->exists(); | |
}); | |
}; | |
// quick way to loop through a pages collection; usage: echo $pages->each('<p>Title: {title}</p>'); | |
pages::$methods['each'] = function($pages, $string) { | |
preg_match_all('/\{(.+?)\}/', $string, $matches); | |
if(isset($matches[1])) { | |
$matches = array_flip($matches[1]); | |
$html = ''; | |
foreach($pages as $p) { | |
$allowed = array_keys($p->content()->toArray()); | |
array_walk($matches, function (&$value, $key) use ($p, $allowed) { | |
if(in_array($key, $allowed)){ | |
return $value = $p->{$key}()->value(); | |
} | |
}, $p); | |
$html .= str::template($string, $matches); | |
} | |
return $html; | |
} | |
}; | |
/** | |
* Creates chunks of random size | |
* | |
* @param int $min Minimum number of items in chunk | |
* @param int $max Maximum number of items in chunk | |
* @return object A new collection with an item for each chunk and a subcollection in each chunk | |
* Usage: | |
* $projects = page('projects')->children()->shuffle(); | |
* $max = mt_rand(1,$projects->count()); | |
* $min = mt_rand(1, $max); | |
* $chunks = $projects->randomChunk($min,$max); | |
*/ | |
pages::$methods['randomChunk'] = function($pages, $min, $max) { | |
$temp = clone $pages; | |
$chunks = []; | |
$size=1; | |
$min = (1 >= $min && $min <= $max) ? $min:1; | |
$max = $max <= $pages->count()? $max: $pages->count(); | |
while ($temp->count() > 0) { | |
$size = mt_rand($min,$max); | |
array_push($chunks, array_splice($temp->data,0, $size)); | |
} | |
$chunkCollections = []; | |
foreach($chunks as $items) { | |
$collection = clone $pages; | |
$collection->data = $items; | |
$chunkCollections[] = $collection; | |
} | |
// convert the array of chunks to a collection object | |
return new Collection($chunkCollections); | |
}; | |
// files methods | |
// search in files (only works with Files object, i.e. $page->files(), not $page->children()->files() etc.) | |
// only works with Files object, i.e. $page->files(), not $page->children()->files() etc. | |
files::$methods['search'] = function($files, $query, $params = array()) { | |
if(is_string($params)) { | |
$params = array('fields' => str::split($params, '|')); | |
} | |
$defaults = array( | |
'minlength' => 2, | |
'fields' => array(), | |
'words' => false, | |
'score' => array() | |
); | |
$options = array_merge($defaults, $params); | |
$collection = clone $files; | |
$searchwords = preg_replace('/(\s)/u',',', $query); | |
$searchwords = str::split($searchwords, ',', $options['minlength']); | |
if(!empty($options['stopwords'])) { | |
$searchwords = array_diff($searchwords, $options['stopwords']); | |
} | |
if(empty($searchwords)) return $collection->limit(0); | |
$searchwords = array_map(function($value) use($options) { | |
return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); | |
}, $searchwords); | |
$preg = '!(' . implode('|', $searchwords) . ')!i'; | |
$results = $collection->filter(function($file) use($query, $searchwords, $preg, $options) { | |
$data = $file->meta()->toArray(); | |
$keys = array_keys($data); | |
if(!empty($options['fields'])) { | |
$keys = array_intersect($keys, $options['fields']); | |
} | |
$file->searchHits = 0; | |
$file->searchScore = 0; | |
foreach($keys as $key) { | |
$score = a::get($options['score'], $key, 1); | |
// check for a match | |
if($matches = preg_match_all($preg, $data[$key], $r)) { | |
$file->searchHits += $matches; | |
$file->searchScore += $matches * $score; | |
// check for full matches | |
if($matches = preg_match_all('!' . preg_quote($query) . '!i', $data[$key], $r)) { | |
$file->searchScore += $matches * $score; | |
} | |
} | |
} | |
return $file->searchHits > 0 ? true : false; | |
}); | |
$results = $results->sortBy('searchScore', SORT_DESC); | |
return $results; | |
}; | |
// quick way to loop through images and create a figure tag for each, usage: $files->each('test'); | |
files::$methods['each'] = function($files, $class=null, $alt=null, $caption=null) { | |
$html = ''; | |
foreach($files as $file) { | |
$html .= kirbytag([ | |
'image' => $file->url(), | |
'class' => $class, | |
'alt' => !is_null($alt)? $file->{$alt}()->value(): null, | |
'caption' => !is_null($caption)? $file->{$caption}()->value(): null, | |
]); | |
} | |
return $html; | |
}; | |
// field methods | |
field::$methods['ktRaw'] = function($field) { | |
$text = $field->kirbytext(); | |
return preg_replace('/(.*)<\/p>/', '$1', preg_replace('/<p>(.*)/', '$1', $text)); | |
}; | |
field::$methods['split'] = function($field) { | |
$string = $field->value(); | |
$matches = preg_split('/([:!?.])/', $string, 2, PREG_SPLIT_DELIM_CAPTURE); | |
if(isset($matches[2]) && $matches[2] !== '') { | |
$title = '<strong>' . $matches[0] . $matches[1] . '</strong>' . $matches[2]; | |
} else { | |
$title = '<strong>' . explode(' ', $string, 2)[0] . '</strong>' . ' ' . explode(' ', $string, 2)[1]; | |
} | |
return $title; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment