Skip to content

Commit

Permalink
Merge pull request #77 from hydephp/update-testimonials
Browse files Browse the repository at this point in the history
Refactor testimonials section to use data collections
  • Loading branch information
caendesilva authored Jun 8, 2024
2 parents 54d795c + eda260d commit 8c69ecb
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 138 deletions.
126 changes: 1 addition & 125 deletions _pages/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,131 +226,7 @@
</div>
</div>
<!-- Start Testimonials -->
<section id="testimonials"
class="flex items-center justify-center w-full px-8 pt-10 md:pt-16 lg:pt-24 xl:pt-40 xl:px-0">
<div class="max-w-6xl mx-auto">
<div class="flex-col items-center ">
<div class="flex flex-col items-center justify-center w-full h-full max-w-2xl pr-8 mx-auto text-center">
<p class="my-5 text-base font-medium tracking-tight text-indigo-500 uppercase">
</p>
<h2 class="text-4xl font-extrabold leading-10 tracking-tight text-gray-900 sm:text-5xl sm:leading-none md:text-6xl lg:text-5xl xl:text-6xl">
Testimonials
</h2>
<p class="my-6 text-xl font-medium text-gray-500">
We are proud to hear that so many people use Hyde to build their websites.
Here are some of our favourite mentions.
</p>
</div>
<div class="flex flex-col items-center justify-center max-w-2xl py-8 mx-auto xl:flex-row xl:max-w-full">
<div class="w-full xl:w-1/2 xl:pr-8">
<blockquote class="my-4 flex flex-col-reverse items-center justify-between w-full col-span-1 p-6 text-center transition-all duration-200 bg-gray-100 rounded-lg md:flex-row md:text-left hover:bg-gray-50 hover:shadow ease">
<div class="flex flex-col sm:pr-8">
<div class="relative sm:pl-12">
<svg class="hidden sm:block absolute left-0 w-10 h-10 text-indigo-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125">
<path
d="M30.7 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2C12.7 83.1 5 72.6 5 61.5c0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S30.7 31.6 30.7 42zM82.4 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2-11.8 0-19.5-10.5-19.5-21.6 0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S82.4 31.6 82.4 42z" />
</svg>
<p class="mt-2 text-base text-gray-600 prose">
Caen (<a href="https://twitter.com/CodeWithCaen?ref_src=twsrc%5Etfw">@CodeWithCaen</a>) has made a website for his PHP-based static-site generator.
<br><br>What I&#39;m mostly impressed with is how clean and straightforward the documentation is. Writing good documentation is an art and Caen did an amazing job at it.
⭐️⭐️⭐️⭐️
</p>
</div>
<h3 class="pl-12 mt-3 text-base font-medium leading-5 text-gray-800 ">
<a href="https://twitter.com/SavvasStephnds" rel="author nofollow">@SavvasStephnds</a>
<span class="mt-1 text-sm leading-5 text-gray-500 ">- <a href="https://twitter.com/SavvasStephnds/status/1534928318503391233?ref_src=twsrc%5Etfw">Via Twitter</a></span>
</h3>
<p class="mt-1 text-sm leading-5 text-gray-500 "></p>
</div>
<img class="flex-shrink-0 object-cover w-24 h-24 mb-5 bg-gray-300 rounded-full md:mb-0"
onerror="this.onerror=null; this.src='https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png';"
src="https://pbs.twimg.com/profile_images/1567450524840075270/tceoqKT2_200x200.png"
alt="Profile image">
</blockquote>
<blockquote class="my-4 hidden lg:flex flex-col-reverse items-center justify-between w-full col-span-1 p-6 mt-12 text-center transition-all duration-200 bg-gray-100 rounded-lg md:flex-row md:text-left hover:bg-gray-50 hover:shadow ease">
<div class="flex flex-col sm:pr-10">
<div class="relative sm:pl-12">
<svg class="hidden sm:block absolute left-0 w-10 h-10 text-indigo-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125">
<path
d="M30.7 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2C12.7 83.1 5 72.6 5 61.5c0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S30.7 31.6 30.7 42zM82.4 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2-11.8 0-19.5-10.5-19.5-21.6 0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S82.4 31.6 82.4 42z" />
</svg>
<p class="mt-2 text-base text-gray-600 prose">Holy f. Your project is definitely one of my favorites of the whole <small>[startup]</small> tournament, I constantly keep an eye on the top 50 for it.
</p>
</div>
<h3 class="pl-12 mt-3 text-base font-medium leading-5 text-gray-800 ">
Felipe Lecot <span class="mt-1 text-sm leading-5 text-gray-500 ">- Director
- <a href="https://do2software.com" class="text-indigo-500" rel="author nofollow" title="External website">Do2 Software</a></span>
</h3>
<p class="mt-1 text-sm leading-5 text-gray-500 "></p>
</div>
<img class="flex-shrink-0 object-cover w-24 h-24 mb-5 bg-gray-300 rounded-full md:mb-0"
onerror="this.onerror=null; this.src='https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png';"
src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
alt="">
</blockquote>
</div>
<div class="w-full xl:w-1/2 xl:pl-8">
<blockquote class="my-4 flex flex-col-reverse items-center justify-between w-full col-span-1 p-6 text-center transition-all duration-200 bg-gray-100 rounded-lg md:flex-row md:text-left hover:bg-gray-50 hover:shadow ease">
<div class="flex flex-col sm:pr-10">
<div class="relative sm:pl-12">
<svg class="hidden sm:block absolute left-0 w-10 h-10 text-indigo-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125">
<path
d="M30.7 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2C12.7 83.1 5 72.6 5 61.5c0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S30.7 31.6 30.7 42zM82.4 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2-11.8 0-19.5-10.5-19.5-21.6 0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S82.4 31.6 82.4 42z" />
</svg>
<p class="mt-2 text-base text-gray-600 prose">
HydePHP is actually simple to setup. Now, I'm not a PHP developer and I can barely write a function in this language, but the project actually delivers on what it promises.
<br><br>
Docs: 10/10
Project: 10/10
</p>
</div>
<h3 class="pl-12 mt-3 text-base font-medium leading-5 text-gray-800 ">
<a href="https://twitter.com/peteralexbizjak" rel="author nofollow">@peteralexbizjak</a>
<span class="mt-1 text-sm leading-5 text-gray-500 ">- <a href="https://twitter.com/peteralexbizjak/status/1535177275649536001">Via Twitter</a></span>
</h3>
<p class="mt-1 text-sm leading-5 text-gray-500 "></p>
</div>
<img class="flex-shrink-0 object-cover w-24 h-24 mb-5 bg-gray-300 rounded-full md:mb-0"
onerror="this.onerror=null; this.src='https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png';"
src="https://pbs.twimg.com/profile_images/1608115407663005696/WflT9L0j_reasonably_small.jpg"
alt="Profile image">
</blockquote>
<blockquote class="my-4 flex flex-col-reverse items-center justify-between w-full col-span-1 p-6 mt-12 text-center transition-all duration-200 bg-gray-100 rounded-lg md:flex-row md:text-left hover:bg-gray-50 hover:shadow ease">
<div class="flex flex-col sm:pr-10">
<div class="relative sm:pl-12">
<svg class="hidden sm:block absolute left-0 w-10 h-10 text-indigo-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125">
<path
d="M30.7 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2C12.7 83.1 5 72.6 5 61.5c0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S30.7 31.6 30.7 42zM82.4 42c0 6.1 12.6 7 12.6 22 0 11-7.9 19.2-18.9 19.2-11.8 0-19.5-10.5-19.5-21.6 0-19.2 18-44.6 29.2-44.6 2.8 0 7.9 2 7.9 5.4S82.4 31.6 82.4 42z" />
</svg>
<p class="mt-2 text-base text-gray-600 prose">Want to have your mention here? Send a Tweet at
<a href="https://twitter.com/HydeFramework">@HydeFramework</a>, and/or use the hashtag
<a href="https://twitter.com/hashtag/HydePHP">#HydePHP</a>!
</p>
</div>
<h3 class="pl-12 mt-3 text-base font-medium leading-5 text-gray-800 ">
This could be you! <span class="mt-1 text-sm leading-5 text-gray-500 ">- CEO
SomeCompany</span>
</h3>
<p class="mt-1 text-sm leading-5 text-gray-500 "></p>
</div>
<img class="flex-shrink-0 object-cover w-24 h-24 mb-5 bg-gray-300 rounded-full md:mb-0"
onerror="this.onerror=null; this.src='https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png';"
src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
alt="">
</blockquote>
</div>
</div>
<footer class="text-center opacity-75">
<small>Testimonials may be edited for formatting, spelling, and brevity, but never content.</small>
<small>Want your own testimonial here? Want to remove yours? This <a class="text-indigo-700" href="https://github.com/hydephp/hydephp.com/blob/master/_pages/index.blade.php">page is open source</a>.</small>
</footer>
</div>
</div>
</section>
@include('testimonials')
<!-- End Testimonials-->
<!-- Blob SVG Border -->
<svg class="absolute bottom-0 w-full text-gray-100 fill-current" viewBox="0 0 1400 74" xmlns="http://www.w3.org/2000/svg"><path d="M0 24C87.243 11.422 173.12 5.133 257.633 5.133 468.305 5.133 578.027 74 700 74c136.015 0 290.882-96.208 481.234-68.867C1268.807 17.71 1341.73 24 1400 24v50H0V24z" /></svg>
Expand Down
18 changes: 18 additions & 0 deletions app/DataCollections/Types/Testimonials.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\DataCollections\Types;

use App\Extend\Concerns\DataCollectionType;

class Testimonials extends DataCollectionType
{
public string $name;
public ?string $title;
public ?string $company;
public ?string $company_url;
public ?string $twitter_link;
public ?string $twitter_username;
public string $markdown;
}
48 changes: 46 additions & 2 deletions app/Extend/Concerns/DataCollectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace App\Extend\Concerns;

use ReflectionClass;
use ReflectionProperty;
use InvalidArgumentException;

/**
* Contract for a custom data collection types.
*
Expand All @@ -11,16 +15,56 @@
*/
abstract class DataCollectionType
{
/**
* Automatically construct the data collection type from an array of collection data.
*
* @param array<string, mixed> $data Where mixed type is generally scalar or array.
*/
public function __construct(array $data = [])
{
foreach ($data as $key => $value) {
$schema = static::schema();

foreach ($schema as $key => $type) {
// Todo: Validate the key against the class properties
// - Validate all required properties are set
// - Validate properties are set to the correct type
// Todo: Set nullable properties to null if not set
// Todo: Add method hooks to run before/after construction

$this->{$key} = $value;
if (array_key_exists($key, $data)) {
$this->{$key} = $data[$key];
} else {
if (str_starts_with($type, '?')) {
$this->{$key} = null;
} else {
throw new InvalidArgumentException(sprintf("Missing required property '%s' for %s.", $key, static::class));
}
}
}
}

/**
* Get the class properties and their types using reflection.
*
* @return array<string, 'class-string'|'array'|'bool'|'callable'|'float'|'int'|'null'|'object'|'string'|'false'|'iterable'|'mixed'|'never'|'true'|'void'|'parent'|'self'|'static'> Associative array of property names over their types.
*/
protected static function schema(): array
{
$reflection = new ReflectionClass(static::class);
$properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);

$schema = [];

foreach ($properties as $property) {
$type = $property->getType()->getName();

if ($property->getType()->allowsNull()) {
$type = '?'.$type; // Indicate nullable type
}

$schema[$property->getName()] = $type;
}

return $schema;
}
}
56 changes: 45 additions & 11 deletions app/Extend/DataCollections.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
namespace App\Extend;

use Hyde\Facades\Filesystem;
use Illuminate\Support\Collection;
use Hyde\Markdown\Models\FrontMatter;
use Illuminate\Support\Str;
use Hyde\Markdown\Models\MarkdownDocument;

/**
* @experimental Typed data collections class extension.
Expand All @@ -22,15 +24,51 @@ public static function yaml(string $name): static
return parent::yaml($name);
}

public static function markdown(string $name): static
{
if (static::hasType($name)) {
return static::getTypedMarkdown($name);
}

return parent::markdown($name);
}

protected static function hasType(string $name): bool
{
return Filesystem::exists(self::getTypePath($name)) || class_exists(self::getTypeClassname($name));
}

/**
* @return static<\App\Extend\Concerns\DataCollectionType>
*/
/** @return static<\App\Extend\Concerns\DataCollectionType> */
protected static function getTypedYaml(string $name): static
{
$className = self::getCallableTypeClassName($name);

return parent::yaml($name)->map(fn (FrontMatter $data) => new $className($data->toArray()));
}

/** @return static<\App\Extend\Concerns\DataCollectionType> */
protected static function getTypedMarkdown(string $name): static
{
$className = self::getCallableTypeClassName($name);
return parent::markdown($name)->reject(fn (MarkdownDocument $document, string $key) => basename($key) === 'README.md') // Patch until https://github.com/hydephp/develop/issues/1716
->map(fn (MarkdownDocument $document) => new $className(array_merge(
$document->matter()->toArray(),
['markdown' => $document->markdown()->body()]
)));
}

protected static function getTypePath(string $name): string
{
return sprintf('%s/%s/type.php', static::$sourceDirectory, $name);
}

protected static function getTypeClassname(string $name): string
{
return 'App\\DataCollections\\Types\\'.Str::studly($name);
}

/** @return class-string<\App\Extend\Concerns\DataCollectionType> */
protected static function getCallableTypeClassName(string $name): string
{
// Load the anonymous class and turn it into a new runtime class
$className = self::getTypeClassname($name);
Expand All @@ -42,17 +80,13 @@ protected static function getTypedYaml(string $name): static
class_alias($newClassName, $className);
}

/** @var \App\Extend\Concerns\DataCollectionType $className */
return parent::yaml($name)->map(fn (FrontMatter $data) => new $className($data->toArray()));
return $className;
}

protected static function getTypePath(string $name): string
protected static function findFiles(string $name, array|string $extensions): Collection
{
return sprintf('%s/%s/type.php', static::$sourceDirectory, $name);
}
// Depends on https://github.com/hydephp/develop/issues/1716

protected static function getTypeClassname(string $name): string
{
return 'App\\DataCollections\\Types\\'.Str::studly($name);
return parent::findFiles($name, $extensions)->reject(fn (string $file) => basename($file) === 'README.md');
}
}
31 changes: 31 additions & 0 deletions resources/collections/testimonials/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# HydePHP Testimonials

In this directory are front mattered Markdown partial files that each will become an entry on the [HydePHP Testimonials](https://hydephp.com#testimonials) homepage section.

## Adding a testimonial

To add a testimonial to the HydePHP Testimonials section, create a new Markdown file in this directory with the following format:

```markdown
---
name: "Author Name"
title: "Job Title" # Optional
company: "Company Name" # Optional
company_url: "https://company.com" # Optional
twitter_link: "https://twitter.com/username/status/1234567890" # If the testimonial was shared on Twitter
twitter_username: "username" # If the testimonial was shared on Twitter, this is used to link to the author name
---

The testimonial content goes here. It should be a brief quote that is no more than a few sentences long.
```

### Editing policy

Testimonials may be edited for formatting, spelling, and brevity, but never content.

### License and permissions

We operate under the assumption that if a testimonial is shared publicly, it is okay for us to share it on the HydePHP website.

If you are the author of a testimonial and would like it removed, you can contact us and we will remove it promptly.
You can also submit a [pull request](https://github.com/hydephp/hydephp.com/tree/master/resources/collections/testimonials) to remove it yourself.
8 changes: 8 additions & 0 deletions resources/collections/testimonials/felipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: "Felipe Lecot"
title: "Director"
company: "Do2 Software"
company_url: "https://do2software.com"
---

Holy f. Your project is definitely one of my favorites of the whole [startup] tournament, I constantly keep an eye on the top 50 for it.
Loading

0 comments on commit 8c69ecb

Please sign in to comment.