Hot answers tagged

6

Craft Plugins require that a "type":"craft-plugin" property is defined in each composer.json file. Composer refers to this to help manage and install the plugin. Craft Modules do not currently have this support. You can see all package types that Composer Installer supports here. There is still a way to achieve what you're trying to do though... Composer ...


5

There is no craft() function in Craft 3 and there are no Modules in Craft 2. You probably mix the two different versions. Craft 3 Craft::$app->getView()->renderTemplate('/path/to/template'); Of course you need to be in the correct namespace. You have to either use Craft or do \Craft Craft 2 craft()->templates->render('path/to/template')


5

You're probably looking for Element::getDirtyAttributes() and Element::getDirtyFields()! The former is for native class properties/attributes (and is based on an ActiveRecord pattern in Yii, I believe...), and the latter is for Craft's "fields," which may or may not be available, based on what type of Element you're looking at (and what FieldLayout ...


4

I haven't tried this tutorial yet, but having learned a lot about Craft 3 from Andrew Welch's other tutorials, I don't doubt this may have some nuggets of useful information to get you on your way. https://nystudio107.com/blog/enhancing-a-craft-cms-3-website-with-a-custom-module


4

I'd make a template called landing that would have various entries/entry types in it where I can add whatever CMS content I want. https://www.example.com/landing/landing-page-slug For a nice content authoring experience, I'd make a custom Element that knows to go out over the wire and fetch the data from the Laravel database via whatever JSON endpoint you'...


4

Per the Modules vs. Plugins docs, only plugins get their own migration track. Modules are considered part of the project (like templates and config files), so if there are any DB changes that need to be made for the module to run, those changes should be made via content migrations. If the module is meant to be reused across multiple projects and does ...


4

Just as a little example how to store files in a custom field /** * @inheritdoc */ public function normalizeValue($value, ElementInterface $element = null) { $namespace = $element? $element->getFieldParamNamespace() . '.' : ''; $file = UploadedFile::getInstanceByName($namespace . $this->handle); if($file !== null){ // replace ...


4

You can change the value in the DB directly instead of using the Elements service $entry = $event->element; $elementId = $entry->id; $siteId = $entry->siteId; Craft::$app->getDb()->createCommand() ->update( '{{%elements_sites}}', ['slug' => ElementHelper::createSlug('new-slug')], [ 'elementId' =&...


4

You were almost there with it. You need to specify a path to an SVG. It can be one of the ones that exists within Craft's icon directory. So your nav item would look like this: Event::on( Cp::class, Cp::EVENT_REGISTER_CP_NAV_ITEMS, function(RegisterCpNavItemsEvent $event) { $event->navItems[] = [ 'url' => 'contact-...


4

When searching the Craft 3.5.x docs for siteName, I see references to Global Variables and General Config Settings. Screenshot: https://cln.sh/egvIXhxZSzaFjeCgNLxX However, AFAICT, it works differently for modules/plugins. As per the Sites section in the Craft 3.5.x Class Reference docs at https://docs.craftcms.com/api/v3/craft-services-sites.html, you would ...


4

It depends on the module handle you chose in config/app.php (the module handle is the key affected to your module in the modules array). If you want the URL to be /business-logic/example/example-route, the module key must be business-logic: use modules\businesslogic\BusinessLogic; return [ 'modules' => [ 'business-logic' => BusinessLogic::...


4

You have 2 solutions: Implement your own Restore action, or Be lazy and reuse \craft\elements\actions I won't cover implementing you own action, let's be lazy! Declare the action To do this, you need to override the defineActions() method of your element's class: protected static function defineActions(string $source = null): array { $actions = parent::...


3

You'll either need to use the action url http://localhost/actions/my-module/scrape/push since only those will route to controllers by default or create a custom route to your controller


3

Yeah you’re correct that db089251 is the culprit here, which fixed a bug where user activation events weren’t getting fired when users were first created, if the “Verify email addresses?” setting was disabled. Your new code is close, but that is going to get called each time Craft tries to activate a user—both when they are first created, and when you try ...


3

That's because groups are not attached to the user directly. At the moment Craft stores the user it hasn't handled the permissions not the user groups. The workflow is Handling all kinds of variables and data Fetch/Create a user Populate the new field values for the user Store the user Handle verifications such as sending them an email Assign the user to ...


3

I've created a stub/reference Adjuster module, here. This demonstrates how to register two Adjusters via a custom module—one that creates a 5% discount on each line item, and one that creates a 10% discount on the entire order. These adjusters have their logic hard-coded, which is to say: in order to modify the behavior/value of the adjustments, you have ...


3

You need to include your template roots Enhancing a Craft CMS 3 Website with a Custom Module public function __construct($id, $parent = null, array $config = []) { Craft::setAlias('@modules/sitemodule', $this->getBasePath()); $this->controllerNamespace = 'modules\sitemodule\controllers'; // Base template directory Event::on(View::...


3

You need to include your module handle to the route module-handle/site/say You also should use the correct namespace instead of app/controllers I suggest you to read the documentation You can as well define a route if you like


3

With a little nudge from Brad, here's the answer: In order to get the module's composer dependencies taken into account in the parent site's composer dependencies, you need to add the module in the parent's composer.json, both as a require and as a repository with the path type, like so: { ... a bunch of stuff from the default composer.json goes here ... ...


3

It must be /admin/module-id/leads. So in your case maybe /admin/leadsmodule/leads or /admin/leads-module/leads depending on your ID if you want to access it directly via template route. Otherwhise you need to create custom URL rules


3

Got in touch with P&T support and got the following response back: We don't currently support parsing JSON via getBodyParams(), however I'm looking into it and looks like Yii can be configured to support that, when the request's Content-Type header is set to application/json. We would need to enable that feature ourselves though. In the meantime ...


3

As of Craft 3.3, if you send a request to Craft with a Content-Type: application/json header, Request::getBodyParam('property') will work as expected, returning the property value from the JSON data in the request body.


3

I figured this out. The table field is expecting JSON: $entry = new Entry(); $entry->sectionId = 1; $entry->typeId = 1; $entry->title = $title; $entry->setFieldValues([ "field_handle" => '[{"col1":"hello","col2":"world"},{"col1":"more","col2":"stuff"}]' ]);


3

I don't think you need to add any composer.json in your module folders You have to update the project composer.json file only to let the craft know about custom module so that it can load on each boot. Folder Structure might be like (inside module folder at the root) wruxmodule └── src ├── controllers │   └── DefaultController.php ├── models ...


3

I am not expert in Craft CMS but this is how it works for me: Depending on the element type, source is different. Look at this link how Craft CMS implements this: https://github.com/craftcms/cms/blob/60881865f1b680c5aa5d4ad8f56d9a1ce3e452b0/src/fields/BaseRelationField.php#L842 Now how assets implement inputsource function: https://github.com/craftcms/...


3

Based on your goal, I don't recommend taking this approach for the technical debt reasons in my comment, however your actual question is still a valid one. You can call any controller's method from a plugin/module like this: Craft::$app->runAction('users/save-user');


3

The cause of the issue turned out to be an incorrect controllerNamespace reference in the Business Logic Template example. If anyone else is using the example project to jumpstart a Craft module, be aware of the following: In that example, the ExampleController.php controller specifies this namespace... namespace modules\businesslogic\controllers; ...but ...


3

You can use entry queries to fetch the entries and the elements service to save them. You can access the element service using Craft::$app->elements. Use Craft::$app->elements->saveElement($entry); to save an entry (or any other element). The best place to put business logic is a service class that you can then call from your controllers. So ...


3

If you don't mind me rearranging your code a bit, I might go with something more like this... Event::on(Entry::class, Entry::EVENT_BEFORE_SAVE, static function (ModelEvent $event) { /** @var Entry $entry */ $entry = $event->sender; // Filter out all Drafts and Revisions if (ElementHelper::isDraftOrRevision($entry)) { Craft::$app-&...


2

Assuming what you're trying to attach is on the local filesystem, you can see an example of this here: https://github.com/pixelandtonic/craftnet/blob/master/src/orders/OrderBehavior.php#L160-L182 Essentially, you'd just use attachContent, but there is also an attach method: ->attachContent($pdf, [ 'fileName' => $filename, 'contentType' => '...


Only top voted, non community-wiki answers of a minimum length are eligible