GithubHelp home page GithubHelp logo

seobundle's Introduction

LeogoutSeoBundle

This bundle provides a simple and flexible API to manage search engine optimization (SEO) tags in your application. Its main goal is to make it simple for you to manage the most common meta, open graph and twitter card tags and to let you configure less common ones with ease.

Test Runner Scrutinizer Code Quality

Installation

Install the bundle with the command:

composer require leogout/seo-bundle

Register the bundle in your AppKernel:

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Leogout\Bundle\SeoBundle\LeogoutSeoBundle(),
        );
    }
}

Configuration

These configuration values are the defaults used to render your tags. See the next section to learn how to override them dynamically.

There are four sections in the config:

  • general: The global configuration. Its values are shared among the other as defaults.
  • basic: A set of the most common SEO tags.
  • og: A set of open graph tags based on http://ogp.me/.
  • twitter: A set of twitter card tags based on https://dev.twitter.com/cards/types

See "Configuration reference" to get the whole configuration.

In your config.yml:

leogout_seo:
    general:
        title: Default title
        description: Default description.
        image: http://images.com/poneys/12/large # This one is shared by open graph and twitter only
    basic:
        title: Awesome title
        keywords: default, keywords
    og:
        type: website
        url: http://test.com/articles
    twitter:
        card: summary
        site: '@leogoutt'

In your view:

<head>
    {{ leogout_seo() }}
</head>

NOTE: You can provide a generator name to the leogout_seo() twig method to render it specifically. For example, to render the basic seo generator, you can use leogout_seo('basic').

The result:

<head>
    <title>Awesome title</title>
    <meta name="description" content="Default description." />
    <meta name="keywords" content="default, keywords" />
    <meta name="og:title" content="Default title" />
    <meta name="og:description" content="Default description." />
    <meta name="og:image" content="http://test.com/articles" />
    <meta name="og:type" content="website" />
    <meta name="twitter:title" content="Default title" />
    <meta name="twitter:description" content="Default description." />
    <meta name="twitter:image" content="http://images.com/poneys/12/large" />
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:site" content="@leogoutt" />
</head>

NOTE: By default, the SEO generators aren't loaded if you don't require them in the config. However, if you want to use the associated generators without configuring any default values (or configuring only the general ones), you can use this notation:

leogout_seo:
   general:
       title: Default title
       description: Default description.
       image: http://images.com/poneys/12/large # This one is shared by open graph and twitter only
   basic: ~
   og: ~
   twitter: ~

Setting values dynamically

You can get the '[basic|twitter|og] as a service to set or override any values. Each value of the configuration can be overrided using a setter of the following form: $this->get('leogout_seo.provider.generator')->get(' [basic|twitter|og] ')->set [config field name] ( [value] )

For example, if you want to change title and robots from basic, you can do this:

class DefaultController extends Controller
{
    public function indexAction()
    {
        $this->get('leogout_seo.provider.generator')->get('basic')
            ->setTitle('Title set in controller')
            ->setRobots(true, false); // they can be chained
        
        return $this->render('AppBundle:Default:index.html.twig');
    }
}

Setting values from a resource

You can configure your own model classes to let the seo generators do all the work thanks to the fromResource() method. Multiple interfaces are available to help the method guess which setters to call to fill the tags.

This is an exemple for the basic generator: In your resource:

use Leogout\Bundle\SeoBundle\Seo\Basic\BasicSeoInterface;

class MyResource implements BasicSeoInterface
{
    protected $name;
    protected $description;
    protected $tags = [];

    // ...Your logic
    
    // These methods are from BasicSeoInterface and have to
    // return a string (or an object with a __toString() method).
    public function getSeoTitle()
    {
        return $this->name; 
    }
    public function getSeoDescription()
    {
        return $this->description; 
    }
    public function getSeoKeywords()
    {
        return implode(',', $this->tags); 
    }
}

In your controller:

class MyController extends Controller
{
    public function indexAction(Request $request)
    {
        $myResource = new MyResource();
        $myResource
            ->setName('Cool resource')
            ->setDescription('Some description')
            ->addKeyword('hey')
            ->addKeyword('ho')
            ->addKeyword('let's go!');
        
        $this->get('leogout_seo.provider.generator')->get('basic')->fromResource($myResource);
        
        return $this->render('MyController:Default:index.html.twig');
    }
}

In your view:

<head>
    {{ leogout_seo('basic') }}
</head>

The result:

<head>
    <title>Cool resource</title>
    <meta name="description" content="Some description" />
    <meta name="keywords" content="hey,ho,let's go!" />
</head>

There are three main interfaces, one for each generator:

  • BasicSeoInterface for basic
  • OgSeoInterface for og
  • TwitterSeoInterface for twitter

These interfaces extends simpler interfaces which you can inplement instead or additionnally. For example, if you only have a meta description on your resource, you can implement DescriptionSeoInterface only to provide a description alone. This is the list of the different interfaces and what they extends:

TitleSeoInterface DescriptionSeoInterface KeywordsSeoInterface ImageSeoInterface
BasicSeoInterface X X X
OgSeoInterface X X X
TwitterSeoInterface X X X

Advanced usage

If the built-in generators don't suit your needs, LeogoutSeoBundle provides a way to create your own SEO generators. First, you have to create a class that extends the AbstractSeoGenerator class:

use Leogout\Bundle\SeoBundle\Seo\AbstractSeoGenerator;

class MyTagsGenerator extends AbstractSeoGenerator
{
    public function setMyTag($content)
    {
        $this->tagBuilder->addMeta('myTag')
            ->setType(MetaTag::NAME_TYPE)
            ->setValue('myAwesomeTag')
            ->setContent((string) $content);

        return $this;
    }

    public function getMyTag()
    {
        return $this->tagBuilder->getMeta('myTag');
    }
}

Then, register it as a service and add it a leogout_seo.generator tag and a custom alias. Don't forget the @leogout_seo.builder dependency:

services:
    app.seo_generator.my_tags:
        class:     AppBundle\Generator\MyTagsGenerator
        arguments: [ '@leogout_seo.builder' ] # This is required
        tags: { name: leogout_seo.generator, alias: my_tags }

That's it, now you can use it alongside the others:

In your controller:

class MyController extends Controller
{
    public function indexAction(Request $request)
    {
        $this->get('leogout_seo.provider.generator')->get('my_tags')->setMyTag('cool');
        
        return $this->render('MyController:Default:index.html.twig');
    }
}

In your view:

<head>
    {{ leogout_seo('my_tags') }}
</head>

Result:

<head>
    <meta name="myAwesomeTag" content="cool" />
</head>

Configuration reference

leogout_seo:
    general:
        title: Default title
        description: Default description.
        image: http://images.com/poneys/12/large
    basic:
        title: Basic title
        description: Basic description.
        keywords: default, keywords
        canonical: http://test.com
        robots:
            index: false
            follow: false
    og:
        title: Open graph title
        description: Open graph description.
        image: http://images.com/poneys/12/large
        type: website # article, book, profile
        url: http://test.com/articles
    twitter:
        title: Twitter title
        description: Twitter description.
        image: http://images.com/poneys/12/thumbnail
        card: summary # summary_large_image
        site: '@leogoutt' # optionnal

Contributing

If you want to contribute (thank you!) to this bundle, here are some guidelines:

  • Please respect the Symfony guidelines
  • Test everything! Please add tests cases to the tests/ directory when:
    • You fix a bug that wasn't covered before
    • You add a new feature
    • You see code that works but isn't covered by any tests (there is a special place in heaven for you)

Todo

  • Packagist

Thanks

Many thanks to the ARCANEDEV/SEO-Helper who authorized me to take some ideas from their library and to KnpMenuBundle which inspired me for the Providers APIs.

seobundle's People

Contributors

innerspirit avatar leogout avatar tugrul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

seobundle's Issues

SeoGeneratorPass::process return type

Currently getting a deprecation warning in Symfony 6.3. I've checked the branch for Symfony 7 and it won't actually cause a problem until Symfony 8.

Method "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::process()" might add "void" as a native return type declaration in the future. Do the same in implementation "Leogout\Bundle\SeoBundle\DependencyInjection\Compiler\SeoGeneratorPass" now to avoid errors or add an explicit @return annotation to suppress this message.

Adding the return type will break backwards compatibility, so perhaps this could be a 2.0 version when Symfony 8 is released, For now the @return annotation can be added. I'm happy to create a PR for the return annotation.

See https://symfony.com/blog/symfony-7-0-type-declarations for more details.

Warning on sf 5.2 - Seo generator services must be public.

Trying this bundle for my Symfony v5.2 (skeleton, not the web-skeleton) got an error

Seo generator services must be public, but "leogout_seo.generator.basic" is not.

it's happen for all generator (basic, og and twitter)

try setting for default, not working

services:
    _defaults:
        public: true

but, add public="true" in the service (seo/basic.xml) can solve the problem, but have no time try to the other major version of symfony.

structure of SEO

Hi would it be possible to consider adding your structure to hand this variable :

http-equiv:
     'Content-Type':         text/html; charset=utf-8
     'X-Ua-Compatible':      IE=EmulateIE7
charset:
     UTF-8:    ''
head:
     "dir" : ltr
     'xmlns':              http://www.w3.org/1999/xhtml
     'xmlns:og':           http://opengraphprotocol.org/schema/

and maybe to get separatly "attributes" ?

<html  {{ leogout_seo_html_attributes()  }}>
       <head {{ leogout_seo_head_attributes() }} >
            {{ leogout_seo() }}
       </head>
</html>

Tank for your help

Generates "name" instead of "property"

The Facebook sharing debugger tool (https://developers.facebook.com/tools/debug/sharing/) gives me a warning about using "name" instead of "property" inside the générated metas, e.g. :

<meta name="og:image" content="..." /> should be <meta property="og:image" content="..." /> according to FB best practices on og tags.

Is there a way to modify this behaviour without modifying the bundle source code directly ?

Add to basicTag

Hi i m'y looking to add MetaTag dynamique how i can do this ?

Symfony 5.3 Bug

hi i try to get install but i still having this issue

Service "leogout_seo.generator.generator" not found:

can you make update ?

Thank

$this->get is not a method in AbstractController

I am using Symfony 6.
When I try to add tags dynamically like this:

$this->get('leogout_seo.provider.generator')->get('basic')
            ->setTitle('Title set in controller')
            ->setRobots(true, false); // they can be chained

I get an error:

Attempted to call an undefined method named "get" of class "App\Controller\BlogController".
Did you mean to call "getSubscribedServices"?

I am following the documentation step by step.

Also tried with DI:

SeoGeneratorProvider $seo 

But then I get:

The SEO generator with alias "leogout_seo.provider.generator" is not defined.

1.2.1 not compatible with Symfony 3.4

The root tree deprecation fix in 1.2.1 uses functions not available until Symfony 4, but composer.json still states it's compatible with 2 and 3. 1.2.0 works OK, but composer installs 1.2.1 by default as it expects it to be compatible.

deprecated since Symfony 4.2

hi have try your bundle and i get error deprecated :

   ›     $treeBuilder = new TreeBuilder();
    ›     $rootNode = $treeBuilder->root('leogout_seo');

are you plan to fix?

Thank

More meta tags like pagination next and previous

Hello i use this package for one of my project for manage SEO tags, but i miss other not essencial tags like rel = next / previous for pagination seo, I locked in one fork of this package by Leadtech this functionality are implemented, will you add these modifications on master SeoBundle?¿

Thanks in advance, i dont know if there is the correct way of tell you that questions...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.