smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.26k stars 712 forks source link

Smarty5: installation without composer #999

Closed lifecom closed 5 months ago

lifecom commented 7 months ago

Is there any way for installation Smarty 5 without composer?

scottchiefbaker commented 7 months ago

With Smarty v4.x there definitely was a way. Checking the docs and the source for v5.x it's not as clear. I would very interested in not using composer as well. If this gets figured out we should update the docs with this info.

wisskid commented 7 months ago

This was discussed here Does this solve your problem?

scottchiefbaker commented 6 months ago

That's pretty nebulous... I'd really like to see "official" documentation on how to do this. I'm not a huge fan of composer.

wisskid commented 6 months ago

Okay. Every (well, almost every, I guess) composer.json file has this section called "autoload".

For Smarty it currently reads:

"autoload": {
        "psr-4" : {
            "Smarty\\" : "src/"
        },
        "files": [
            "src/functions.php"
        ]
    },

So, register a PSR-4 autoloader for the Smarty namespace that reads from the src folder and include src/functions.php once.

That should do it.

scottchiefbaker commented 6 months ago

For Smarty 4.x my instantiation is:

require("include/smarty/libs/Smarty.class.php");
$smarty = new Smarty();

I've been doing it that way for 8+ years on Smarty 3.x and 4.x. I'd like to do something similar with Smarty 5.x.

require("smarty-5.0.2/src/functions.php");

use Smarty\Smarty;
$smarty = new Smarty();

I get Fatal error: Uncaught Error: Class "Smarty\Smarty" not found in... What am I doing wrong? I'm not familiar with PSR-4 autoloaders.

scottchiefbaker commented 6 months ago

FWIW I'm 100% willing to write up some documentation and submit a PR for how load Smarty without composer once I get it working. Clearly there are other people that desire this functionality as well. It would be good to have it in the official documentation.

wisskid commented 6 months ago

I asked ChatGPT to write it, seems like this might work:


spl_autoload_register(function ($class) {
    // Namespace prefix
    $prefix = 'Smarty\\';

    // Base directory for the namespace prefix
    $baseDir = __DIR__ . '/a/b/src/';

    // Does the class use the namespace prefix?
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // If not, move to the next registered autoloader
        return;
    }

    // Get the relative class name
    $relativeClass = substr($class, $len);

    // Replace namespace prefix with base directory, replace namespace separators with directory separators, and append .php
    $file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';

    // If the file exists, require it
    if (file_exists($file)) {
        require $file;
    }
});

If not, just run composer require smarty/smarty && composer dump-autoload and see what's in vendor/autoload.php

lifecom commented 6 months ago

You don’t necessarily need Composer

wblessen commented 6 months ago

FWIW I'm 100% willing to write up some documentation and submit a PR for how load Smarty without composer once I get it working. Clearly there are other people that desire this functionality as well. It would be good to have it in the official documentation.

I am happy with Composer., it makes my life much easier. Writing autoloaders with public constants is long long time ago, I dont miss that

Using Composer, put everything with PSR-4 together and thats it.

Without composer, the day, someone in Smarty decides to load another library with composer you are done.

So I am just curious, why you dont use it?

scottchiefbaker commented 6 months ago

@wblessen my application is very simple. I haven't needed the complexity of composer for any projects yet. Smarty used to be able to be loaded without composer. I'm just trying to keep things simple.

scottchiefbaker commented 6 months ago

I reworked some of the above and came up with the following load_smarty.php file that does most of what composer does.

define('SMARTY_DIR', "/home/username/html/include/smarty/src/");

spl_autoload_register(function ($class) {
    // Class prefix
    $prefix = 'Smarty\\';

    // If we are not a member of above class skip
    if (!str_starts_with($class, $prefix)) { return; }

    // Hack off the prefix part
    $relative_class = substr($class, strlen($prefix));

    // Build a path to the include file
    $file = SMARTY_DIR . str_replace('\\', '/', $relative_class) . '.php';

    // If the file exists, require it
    if (file_exists($file))  { require_once($file); }
});

Then in another script I have

require_once("load_smarty.php");

// Instantiate the class
$obj = new Smarty\Smarty();

I need to do some more testing, but this appears to work.

wisskid commented 6 months ago

Don't forget src/functions.php!

scottchiefbaker commented 6 months ago

Oh good call... I wrote up my implementation and submitted a PR to allow using Smarty without Composer.

juangacovas commented 6 months ago

Thanks Scott, I was also looking for this when we try to migrate to v5 soon.

On Tue, May 14, 2024 at 9:18 PM Scott Baker @.***> wrote:

Oh good call... I wrote up my implementation and submitted a PR to allow using Smarty without Composer.

— Reply to this email directly, view it on GitHub https://github.com/smarty-php/smarty/issues/999#issuecomment-2110978097, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI7NGIG5SRQOW2JREA3XBTZCJPR5AVCNFSM6AAAAABGOAHDNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJQHE3TQMBZG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

jasonnug commented 6 months ago

I haven't needed composer yet for my projects so I was looking for this. Thanks.

emaeba commented 6 months ago

It worked without composer. thank you. I think Smarty needs an option without Composer.

gtraxx commented 6 days ago

I upgrade my smarty 4 version to smarty 5 but the structure is completely different and I don't understand anything to adapt my current code (my class which extends)

<?php
/**
 * Extend class smarty
 *
 */
class frontend_model_smarty extends Smarty{
    /**
    * Variable statique permettant de porter l'instance unique
    */
    static protected $instance;
    protected $template;
    /**
     * function construct class
     *
     */
    public function __construct($t){
        /**
         * include parent var smarty
         */
        parent::__construct(); 
        self::setParams($t);
        /*
         You can remove this comment, if you prefer this JSP tag style
         instead of the default { and }
         $this->left_delimiter =  '<%';
         $this->right_delimiter = '%>';
         */
    }
    private function setPath(){
        return component_core_system::basePath();
    }

    /**
     * @param $t
     * @return void
     * @throws SmartyException
     */
    protected function setParams($t = null){
        $template = $t instanceof frontend_model_template ? $t : new frontend_model_template();

        /**
         * Path -> configs
         */
        $this->setConfigDir(array(
            self::setPath()."locali18n/",
            self::setPath() . "skin/" . $template->theme . '/i18n/'
        ));
        /**
         * additionnal Path -> configs
         */
        /**
         * Path -> templates
         */
        $this->setTemplateDir(array(
            self::setPath()."skin/".$template->theme.'/'
        ));

        /**
         * path plugins
         * @var void
         */
        $this->setPluginsDir(array(
            self::setPath().'lib/smarty4/plugins/'
            ,self::setPath().'app/wdcore/'
            ,self::setPath().'widget/'
        ));
        /**
         * Ajout du dossier additionnels des plugins smarty dans le template courant
         */
        $template->addWidgetDir(
            $this,
            self::setPath(),
            false
        );
        /**
         * Path -> compile
         */
        $this->setCompileDir(
            self::setPath().'var/templates_c/'
        );
        /**
         * debugging (true/false)
         */
        $this->debugging = false;
        /**
         * compile (true/false)
         */
        $this->compile_check = true;
        $this->config_booleanize = false;
        /**
         * Force compile
         * @var void
         * (true/false)
         */
        $this->force_compile = false;
        /**
         * caching (true/false)
         */
        $template->setCache($this);

        /**
         * Use sub dirs (true/false)
         */
        $this->use_sub_dirs = false;
        /**
         * cache_dir -> cache
         */
        $this->setCacheDir(
            self::setPath().'var/tpl_caches/'
        );
        /**
         * load pre filter
         */
        $this->loadFilter('output', 'trimwhitespace');
        $this->loadPlugin('smarty_compiler_switch');
        /**
         * 
         * @var error_reporting
         */
        $this->error_reporting = error_reporting() &~E_NOTICE;
    }
    public static function getInstance($t = null){
        if (!isset(self::$instance))
      {
         self::$instance = new frontend_model_smarty($t);
      }
        return self::$instance;
    }
}
?>
Capture d’écran 2024-11-20 à 16 57 00