# Structs

Structs are a code representation of HTML head elements.

# Available Shorthand Methods

Shorthand methods are predefined shortcuts to add commonly used Structs without the hassle of importing struct classes or chain many methods.

When using shorthand methods, you will skip the seo()->add() method. You can configure which Structs should be added on shorthand calls in the seo.php config file under the shorthand key.

# Title

seo()->title(string $title = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Title;
use romanzipp\Seo\Structs\Meta;

seo()->addMany([

    Title::make()
        ->body(string $title = null),

    Meta\OpenGraph::make()
        ->property('title')
        ->content(string $title = null),

    Meta\Twitter::make()
        ->name('title')
        ->content(string $title = null),

]);
renders to ...
<title>{title}</title>
<meta property="og:title" content="{title}" />
<meta name="twitter:title" content="{title}" />

# Description

seo()->description(string $description = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Meta;

seo()->addMany([

    Meta\Description::make()
        ->name('description')
        ->content(string $description = null),

    Meta\OpenGraph::make()
        ->property('description')
        ->content(string $description = null),

    Meta\Twitter::make()
        ->name('description')
        ->content(string $description = null),

]);
renders to ...
<meta name="description" content="{description}" />
<meta property="og:description" content="{description}" />
<meta name="twitter:description" content="{description}" />

# Image

seo()->image(string $image = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Meta;

seo()->addMany([

    Meta::make()
        ->name('image')
        ->content($image, $escape),
    
    
    Meta\OpenGraph::make()
        ->property('image')
        ->content($image, $escape),
    
    
    Meta\Twitter::make()
        ->name('image')
        ->content($image, $escape),

]);
renders to ...
<meta name="image" content="{image}" />
<meta property="og:image" content="{image}" />
<meta name="twitter:image" content="{image}" />

# Meta

seo()->meta(string $name, $content = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Meta;

seo()->add(
    Meta::make()
        ->name(string $name, bool $escape = true)
        ->content($content = null, bool $escape = true)
);
renders to ...
<meta name="{name}" content="{content}" />

# OpenGraph

seo()->og(string $property, $content = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Meta\OpenGraph;

seo()->add(
    OpenGraph::make()
        ->property(string $property, bool $escape = true)
        ->content($content = null, bool $escape = true)
);
renders to ...
<meta name="og:{property}" content="{content}" />

# Twitter

seo()->twitter(string $name, $content = null, bool $escape = true);
same as ...
use romanzipp\Seo\Structs\Meta\Twitter;

seo()->add(
    Twitter::make()
        ->name(string $name, bool $escape = true)
        ->content($content = null, bool $escape = true)
);
renders to ...
<meta name="twitter:{name}" content="{content}" />

# Canonical

seo()->canonical(string $canonical);
same as ...
use romanzipp\Seo\Structs\Link\Canonical;

seo()->add(
    Canonical::make()
        ->href($canonical = null)
);
renders to ...
<link rel="canonical" href="{canonical}" />

# CSRF Token

seo()->csrfToken(string $token = null);
same as ...
use romanzipp\Seo\Structs\Meta\CsrfToken;

seo()->add(
    CsrfToken::make()
        ->token($token = null)
);
renders to ...
<meta name="csrf-token" content="{token}" />

# Adding single structs

If you need to use more advanced elements which are not covered with shorthand setters, you can easily add single structs to your SEO instance the following way.

Remember: There are many methods available for adding new structs

# Titles

use romanzipp\Seo\Structs\Title;

seo()->add(
    Title::make()->body('This is a Title')
);
<title>This is a Title</title>

# Meta Tags

Using the attr(string $attribute, $value = null) method, we can append attributes with given values.

use romanzipp\Seo\Structs\Meta;

seo()->add(
    Meta::make()
        ->attr('name', 'theme-color')
        ->attr('content', 'red')
);
<meta name="theme-color" content="red" />

# OpenGraph

Because OpenGraph tags are <meta /> elements, the OpenGraph Struct extends the Meta class.

All OpenGraph elements are defined by property="" and content="" attributes where the property value starts with a og: prefix.

Instead of using the attr() Struct method, we can use the shorthand property() and content() methods by the OpenGraph class.

use romanzipp\Seo\Structs\Meta\OpenGraph;

seo()->add(
    OpenGraph::make()
        ->attr('property', 'og:site_name')
        ->attr('content', 'Laravel')
);
use romanzipp\Seo\Structs\Meta\OpenGraph;

seo()->add(
    OpenGraph::make()
        ->property('site_name')
        ->content('Laravel')
);

... both render to ...

<meta property="og:site_name" content="Laravel" />

# Twitter

Twitter meta tags share the same behavior as OpenGraph tags while the property prefix is twitter:.

use romanzipp\Seo\Structs\Meta\Twitter;

seo()->add(
    Twitter::make()
        ->attr('name', 'twitter:card')
        ->attr('content', 'summary')
);
use romanzipp\Seo\Structs\Meta\Twitter;

seo()->add(
    Twitter::make()
        ->name('card')
        ->content('summary')
);

... both render to ...

<meta name="twitter:card" content="summary" />

# Available Structs

# Base

romanzipp\Seo\Structs\Base::make();
romanzipp\Seo\Structs\Link::make();
romanzipp\Seo\Structs\Link\Canonical::make();

# Meta

romanzipp\Seo\Structs\Meta::make();
romanzipp\Seo\Structs\Meta\Article::make()
    ->property(string $value, bool $escape = true)
    ->content(string $value, bool $escape = true);
romanzipp\Seo\Structs\Meta\AppLink::make()
    ->property(string $value, bool $escape = true)
    ->content(string $value, bool $escape = true);
romanzipp\Seo\Structs\Meta\Charset::make()
    ->charset(string $charset, bool $escape = true);
romanzipp\Seo\Structs\Meta\CsrfToken::make()
    ->token($token = null, bool $escape = true);
romanzipp\Seo\Structs\Meta\Description::make();
romanzipp\Seo\Structs\Meta\OpenGraph::make()
    ->property(string $value, bool $escape = true)
    ->content(string $value = null, bool $escape = true);
romanzipp\Seo\Structs\Meta\Twitter::make()
    ->name(string $value, bool $escape = true)
    ->content(string $value, bool $escape = true);
romanzipp\Seo\Structs\Meta\Viewport::make()
    ->content(string $content, bool $escape = true);

# Noscript

romanzipp\Seo\Structs\Noscript::make();

# Script

romanzipp\Seo\Structs\Script::make();

# Title

romanzipp\Seo\Structs\Title::make();

# Escaping

By default, all body and attribute content is escaped via the Laravel e() (opens new window) helper function. You can change this behavior by setting the $escape parameter on all attribute setters.

Use this feature with caution!

use romanzipp\Seo\Structs\Title;

Title::make()->body('Dont \' escape me!', false);
use romanzipp\Seo\Structs\Meta;

Meta::make()->attr('content', 'Dont \' escape me!', false);

# Creating custom Structs

You can create your own Structs simply by extending the romanzipp\Seo\Structs\Struct class.

use romanzipp\Seo\Structs\Struct;

class MyStruct extends Struct
{
    //
}

We differentiate between void elements (opens new window) and normal elements. Void elements, like <meta /> can not have a closing tag other than normal elements like <title></title>.

# Tag

A struct always requires a tag. This can be set by implementing the abstract tag() method.

protected function tag(): string
{
    return 'script';
}

# Uniqueness

Certain elements in a documents <head> can only exist once, like the <title></title> element.

By default, Structs are not unique. To change this behavior, apply the unique property.

protected $unique = true;

Now, previously created Structs will be overwritten.

use romanzipp\Seo\Structs\Struct;

class MyStruct extends Struct
{
   public static function defaults(self $struct): void
   {
       $struct->attr('name', 'my-description');
   }
   
   protected function tag(): string
   {
       return 'meta';
   }
}

seo()->add(MyStruct::make()->attr('name', 'This is the FIRST description'));
seo()->add(MyStruct::make()->attr('name', 'This is the SECOND description'));

Before:

<meta name="my-description" content="This is the FIRST description" />
<meta name="my-description" content="This is the SECOND description" />

After:

<meta name="my-description" content="This is the SECOND description" />

You are also able to modify the unique attributes by setting the uniqueAttributes property. If empty, just the tag name will be considered as unique.

protected $uniqueAttributes = ['name'];

# Defaults

After a Struct instance has been created, we call the static defaults method.

use romanzipp\Seo\Structs\Struct;

class MyStruct extends Struct
{
    public function __construct()
    {
        static::defaults($this);
    }

    public static function defaults(self $struct): void
    {
        //
    }
}

By implementing the defaults method on your custom Struct, you can run any custom logic like adding default attributes.

This is used among others in the romanzipp\Seo\Structs\Meta\Charset Struct to set a default charset attribute.

use romanzipp\Seo\Structs\Meta;
use romanzipp\Seo\Structs\Struct;

class Charset extends Meta
{
    public static function defaults(Struct $struct): void
    {
        $struct->addAttribute('charset', 'utf-8');
    }
}