This was my entities and fields presentation from Drupalcamp Colorado 2020.
http://drupalcampcolorado.org/sessions/drupal-7-entities-and-fields-transitioning-d7
Modeling Tricks My Relational Database Never Taught MeDavid Boike
In this session we will explore several modeling scenarios from my own experience that can easily be achieved using RavenDB, but difficult (if not nearly impossible) to build using a classic relational database. The focus will be on helping those accustomed to SQL Server or other relational databases learn good document modeling skills by example, with a summary of document modeling guidelines at the end.
Drupal 8: A story of growing up and getting off the islandAngela Byron
The Drupal project has traditionally held a strong internal value for doing things "The Drupal Way." As a result, Drupal developers have historically needed to build up reams and reams of tricks and workarounds that were specific to Drupal itself, and Drupal was inaccessible to people with a more traditional programming background. Starting in Drupal 8, however, we've effectively done a ground-up rewrite of the underlying code and in the process made major inroads to getting more inline with the rest of the PHP world. Procedural code is out, OO code is in. "Creative" hacks have been replaced with FIG standards. "Not invented here" is now "Proudly found elsewhere." This story will talk about the journey that Drupal 8 and the Drupal core development team has taken during this transition over the past 3+ years, including some of the pros and cons of this approach and how we dealt (and are dealing) with some of the community management challenges that resulted.
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018Mike Harris
I never wrote it; everybody else did! How many times have you waded through an ageing, decaying, tangled forrest of code and wished it would just die? How many times have you heard someone say that what really needs to happen is a complete rewrite? I have heard this many times, and, have uttered that fatal sentence myself. But shouldn’t we love our legacy code? Doesn’t it represent our investment and the hard work of ourselves and our predecessors? Throwing it away is dangerous, because, before we do, we’ll need to work out exactly what it does, and we’ll need to tweeze out that critical business logic nestled in a deeply entangled knot of IF statements. It could take us years to do, and we’ll have to maintain two systems whilst we do it, inevitably adding new features to them both. Yes we get to reimplement using the latest, coolest programming language, instead of an old behemoth, but how long will our new cool language be around, and who will maintain that code, when it itself inevitably turns to legacy? We can throw our arms in the air, complaining and grumbling about how we didn’t write the code, how we would never have written it the way it is, how those that wrote it were lesser programmers, possibly lesser humans themselves, but the code still remains, staring us in the face and hanging around for longer that we could possibly imagine. We can sort it out, we can improve it, we can make it testable, and we can learn to love our legacy code.
https://www.youtube.com/watch?v=qRP45l5UugE
Xcore is a textual format to define ecore models. This not only makes editing and reading much more convenient but has other cool advantages as well. Xcore, for instance, allows to embed Xbase expressions to define logic within EOperations and the like.
In this session you will learn, why and when using Xcore is a good idea and how to use it with Xtext languages. I will explain talk about which URIs to use, and how to properly configure the MWE2 file as well as more complicated setups, with multiple languages and mixtures of ecore, xcore and generated models.
This presentation walks you through how to create and use custom shortcodes throughout your WordPress website, adding in anything from a simple header to an advanced nested layout.
This was my entities and fields presentation from Drupalcamp Colorado 2020.
http://drupalcampcolorado.org/sessions/drupal-7-entities-and-fields-transitioning-d7
Modeling Tricks My Relational Database Never Taught MeDavid Boike
In this session we will explore several modeling scenarios from my own experience that can easily be achieved using RavenDB, but difficult (if not nearly impossible) to build using a classic relational database. The focus will be on helping those accustomed to SQL Server or other relational databases learn good document modeling skills by example, with a summary of document modeling guidelines at the end.
Drupal 8: A story of growing up and getting off the islandAngela Byron
The Drupal project has traditionally held a strong internal value for doing things "The Drupal Way." As a result, Drupal developers have historically needed to build up reams and reams of tricks and workarounds that were specific to Drupal itself, and Drupal was inaccessible to people with a more traditional programming background. Starting in Drupal 8, however, we've effectively done a ground-up rewrite of the underlying code and in the process made major inroads to getting more inline with the rest of the PHP world. Procedural code is out, OO code is in. "Creative" hacks have been replaced with FIG standards. "Not invented here" is now "Proudly found elsewhere." This story will talk about the journey that Drupal 8 and the Drupal core development team has taken during this transition over the past 3+ years, including some of the pros and cons of this approach and how we dealt (and are dealing) with some of the community management challenges that resulted.
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018Mike Harris
I never wrote it; everybody else did! How many times have you waded through an ageing, decaying, tangled forrest of code and wished it would just die? How many times have you heard someone say that what really needs to happen is a complete rewrite? I have heard this many times, and, have uttered that fatal sentence myself. But shouldn’t we love our legacy code? Doesn’t it represent our investment and the hard work of ourselves and our predecessors? Throwing it away is dangerous, because, before we do, we’ll need to work out exactly what it does, and we’ll need to tweeze out that critical business logic nestled in a deeply entangled knot of IF statements. It could take us years to do, and we’ll have to maintain two systems whilst we do it, inevitably adding new features to them both. Yes we get to reimplement using the latest, coolest programming language, instead of an old behemoth, but how long will our new cool language be around, and who will maintain that code, when it itself inevitably turns to legacy? We can throw our arms in the air, complaining and grumbling about how we didn’t write the code, how we would never have written it the way it is, how those that wrote it were lesser programmers, possibly lesser humans themselves, but the code still remains, staring us in the face and hanging around for longer that we could possibly imagine. We can sort it out, we can improve it, we can make it testable, and we can learn to love our legacy code.
https://www.youtube.com/watch?v=qRP45l5UugE
Xcore is a textual format to define ecore models. This not only makes editing and reading much more convenient but has other cool advantages as well. Xcore, for instance, allows to embed Xbase expressions to define logic within EOperations and the like.
In this session you will learn, why and when using Xcore is a good idea and how to use it with Xtext languages. I will explain talk about which URIs to use, and how to properly configure the MWE2 file as well as more complicated setups, with multiple languages and mixtures of ecore, xcore and generated models.
This presentation walks you through how to create and use custom shortcodes throughout your WordPress website, adding in anything from a simple header to an advanced nested layout.
A fun-filled evening with great food, great speeches, great wine and superb company! Thank you Toastmasters from other clubs for joining us. Hope to see you all again next year!
Ready. Set. Drupal! An Intro to Drupal 8, Part 2Acquia
In this two part series, we'll give you a quick introduction to the Drupal 8 out-of-the-box site building experience. This course is for people who are completely new to Drupal. You might be a developer or a decision maker, but you need to know what makes Drupal tick, and fast.
In part 2, you’ll get an overview of site building, extending Drupal, and contributing to the Drupal community. This course includes:
• Presentations: We've condensed the most essential information about Drupal into this quick course.
• Demos: Watch me completing specific tasks as I build a site.
• Download step-by-step tutorials, and try out the tasks yourself.
No matter your experience level or background, this course will get you familiar with the next up-and-coming version of Drupal.
https://www.acquia.com/resources/acquia-tv/conference/ready-set-drupal-intro-drupal-8-part-2-december-4-2014
An introduction to C++. These slides were used to guide a presentation on C++. The target audience was programmers learning C++ for the first time. As such the content covered basics of modern C++ and some other things that I feel was helpful to know about when starting with C++.
A fun-filled evening with great food, great speeches, great wine and superb company! Thank you Toastmasters from other clubs for joining us. Hope to see you all again next year!
Ready. Set. Drupal! An Intro to Drupal 8, Part 2Acquia
In this two part series, we'll give you a quick introduction to the Drupal 8 out-of-the-box site building experience. This course is for people who are completely new to Drupal. You might be a developer or a decision maker, but you need to know what makes Drupal tick, and fast.
In part 2, you’ll get an overview of site building, extending Drupal, and contributing to the Drupal community. This course includes:
• Presentations: We've condensed the most essential information about Drupal into this quick course.
• Demos: Watch me completing specific tasks as I build a site.
• Download step-by-step tutorials, and try out the tasks yourself.
No matter your experience level or background, this course will get you familiar with the next up-and-coming version of Drupal.
https://www.acquia.com/resources/acquia-tv/conference/ready-set-drupal-intro-drupal-8-part-2-december-4-2014
An introduction to C++. These slides were used to guide a presentation on C++. The target audience was programmers learning C++ for the first time. As such the content covered basics of modern C++ and some other things that I feel was helpful to know about when starting with C++.
Drupal upgrades and migrations. BAD Camp 2013 versionDavid Lanier
Originally presented at PNW Drupal Summit 2013. Revised for BADCamp 2013.
You have an aging Drupal 6 or even a Drupal 5 site. You know it's time to move up to Drupal 7. Now, how? There are two main ways to get there. You can perform a traditional upgrade, or you can migrate the data from the old site to a brand new site. In this session I will show how you can use these methods and discuss their benefits and drawbacks, including a thought process to go through when evaluating these options, drawing from some recent projects.
Walks through the top 8 improvements coming to Drupal 8, including videos and code samples to demonstrate "before vs. after."
Given to the @DrupalNS meet up in Bedford, Nova Scotia on July 28, 2014.
What are entities in Drupal 8 and how does that differ from Drupal 7. How can you leverage all the power of entities in Drupal 8 and why you should definitely use them!
Introducing Exhibit pattern. Or how to program controllers and views in such a way that you don't need that many if-statements.
Fully Test-Driven solution.
Presentation I gave at the Berkeley Drupal Users Group on February 27, 2012 covering entities in Drupal 7 including entity types, bundles, fields, nodes, the Entity API and the Schema API. I use TextbookMadness.com as an example of how to leverage entities.
Click on my name to find a newer (better!) version of these slides.
drupal 7 amfserver presentation: integrating flash and drupalrolf vreijdenberger
In this presentation there will be a full explanation of how to integrate flash and drupal 7 with the amfserver module. Including examples and best practices. Presentation by the author of the amfserver module held at the 2011 DrupalCamp Sweden in Stockholm
Domain-driven design is a collaborative process involving both domain experts and software practitioners. This high-level overview takes a look at the driving principles behind domain-driven design. It also explores domain-driven design's building block patterns, supple design, strategic design, and distillation of the core.
This video is from a a college level course taught at the Florida Polytechnic University located in Lakeland Florida. The purpose of this course is to introduce Freshmen students to what design patterns are and how to use them.
in this class session, Dr. Anderson introduces object orientated programming, covers abstraction, encapsulation, polymorphism, and inheritance. He then wraps things up with a discussion of the differences between composition and inheritance..
The Instructor is Dr. Jim Anderson.
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
Keynote at DIGIT West Expo, Glasgow on 29 May 2024.
Cheryl Hung, ochery.com
Sr Director, Infrastructure Ecosystem, Arm.
The key trends across hardware, cloud and open-source; exploring how these areas are likely to mature and develop over the short and long-term, and then considering how organisations can position themselves to adapt and thrive.
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
After immersing yourself in the blue book and its red counterpart, attending DDD-focused conferences, and applying tactical patterns, you're left with a crucial question: How do I ensure my design is effective? Tactical patterns within Domain-Driven Design (DDD) serve as guiding principles for creating clear and manageable domain models. However, achieving success with these patterns requires additional guidance. Interestingly, we've observed that a set of constraints initially designed for training purposes remarkably aligns with effective pattern implementation, offering a more ‘mechanical’ approach. Let's explore together how Object Calisthenics can elevate the design of your tactical DDD patterns, offering concrete help for those venturing into DDD for the first time!
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
4. This is Code Heavy
• We will be discussing
code
• If you are not a coder this
will probably be
incredibly boring to you
5. This is Code Heavy
• We will be discussing
code
• If you are not a coder this
will probably be
incredibly boring to you
• We are not responsible
for what may happen to
you if you fall asleep.
7. The Next Hour
• Lots of content and fast talking. Save questions
until the end
8. The Next Hour
• Lots of content and fast talking. Save questions
until the end
• Discuss key concepts in Drupal 7: Bundles,
Entities and Fields
9. The Next Hour
• Lots of content and fast talking. Save questions
until the end
• Discuss key concepts in Drupal 7: Bundles,
Entities and Fields
• Walk through the creation of a content type
that will add a Bundle of Fields complete
with custom Formatters to the node Entity
10. The Next Hour
• Lots of content and fast talking. Save questions
until the end
• Discuss key concepts in Drupal 7: Bundles,
Entities and Fields
• Walk through the creation of a content type
that will add a Bundle of Fields complete
with custom Formatters to the node Entity
• Explain WTH that last comment meant
11. The Next Hour
• Lots of content and fast talking. Save questions
until the end
• Discuss key concepts in Drupal 7: Bundles,
Entities and Fields
• Walk through the creation of a content type
that will add a Bundle of Fields complete
with custom Formatters to the node Entity
• Explain WTH that last comment meant
• Introduce the most excellent node_example
module
13. Key Concept
Entity
• An Entity is a container for Bundles.
14. Key Concept
Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
15. Key Concept
Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
• Examples are Node, User, File, Taxonomy Term,
Taxonomy Vocabulary
16. Key Concept
Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
• Examples are Node, User, File, Taxonomy Term,
Taxonomy Vocabulary
• Why not make everything an Entity?
18. Key Concept
Bundles
• A Bundle is a set of fields that are treated as a
group by the Field API
19. Key Concept
Bundles
• A Bundle is a set of fields that are treated as a
group by the Field API
• Bundles are similar in concept to a node type in
Drupal 6
21. Key Concept
Fields
• A field defines a particular type of data that can
be attached to any entity and can be shared
between entities
22. Key Concept
Fields
• A field defines a particular type of data that can
be attached to any entity and can be shared
between entities
• A field can have Widgets. A widget is the UI
element that allows a user to enter data into the
field
23. Key Concept
Fields
• A field defines a particular type of data that can
be attached to any entity and can be shared
between entities
• A field can have Widgets. A widget is the UI
element that allows a user to enter data into the
field
• A field can have Formatters. A formatter defines
how a fields data gets displayed in a view mode
25. The Examples Module
• In my mind, the best resource for learning is the
Examples Modue
26. The Examples Module
• In my mind, the best resource for learning is the
Examples Modue
• This module used to live exclusively in CVS but is
now maintained by rfay, Dave Reid, katbailey
and ilo in contrib
27. The Examples Module
• In my mind, the best resource for learning is the
Examples Modue
• This module used to live exclusively in CVS but is
now maintained by rfay, Dave Reid, katbailey
and ilo in contrib
• Documentation can be viewed from
api.drupal.org by following the Examples link
28. The Examples Module
• In my mind, the best resource for learning is the
Examples Modue
• This module used to live exclusively in CVS but is
now maintained by rfay, Dave Reid, katbailey
and ilo in contrib
• Documentation can be viewed from
api.drupal.org by following the Examples link
• drupal.org/project/examples - not just the node
module
32. D7 *.install
• We still implement hook_install() and
hook_uninstall()
33. D7 *.install
• We still implement hook_install() and
hook_uninstall()
• hook_schema() no longer needs to be explicitly
called
34. D7 *.install
• We still implement hook_install() and
hook_uninstall()
• hook_schema() no longer needs to be explicitly
called
• Database structure will resemble D6 CCK tables
35. D7 *.install
• We still implement hook_install() and
hook_uninstall()
• hook_schema() no longer needs to be explicitly
called
• Database structure will resemble D6 CCK tables
• Database Entity revisions are provided
automatically
38. /**
* Implements hook_install().
*
*/
function node_example_install() {
...
}
/**
* Return a structured array defining the fields created by this content type.
*
* This is packaged in a function so it can be used in both hook_install()
* and hook_uninstall().
*/
function _node_example_installed_fields() {
...
}
39. /**
* Implements hook_install().
*
*/
function node_example_install() {
...
}
/**
* Return a structured array defining the fields created by this content type.
*
* This is packaged in a function so it can be used in both hook_install()
* and hook_uninstall().
*/
function _node_example_installed_fields() {
...
}
/**
* Return a structured array defining the instances for this content type.
*
* The instance lets Drupal know which widget to use to allow the user to enter
* data and how to react in different view modes.
* This is provided as a function so that it can be used in both hook_install()
* and hook_uninstall().
*/
function _node_example_installed_instances() {
...
}
40. /**
* Implements hook_install().
*
*/
function node_example_install() {
...
}
/**
* Return a structured array defining the fields created by this content type.
*
* This is packaged in a function so it can be used in both hook_install()
* and hook_uninstall().
*/
function _node_example_installed_fields() {
...
}
/**
* Return a structured array defining the instances for this content type.
*
* The instance lets Drupal know which widget to use to allow the user to enter
* data and how to react in different view modes.
* This is provided as a function so that it can be used in both hook_install()
* and hook_uninstall().
*/
function _node_example_installed_instances() {
...
}
/**
* Implements hook_uninstall().
*
*/
function node_example_uninstall() {
...
}
43. D7 *.install
• hook_install() will set up our content type
• hook_install() is where we create our fields, if
needed
44. D7 *.install
• hook_install() will set up our content type
• hook_install() is where we create our fields, if
needed
• hook_install() is used to tie our fields to an
Entity as a Bundle
47. function node_example_install() {
$types = node_type_get_types();
node_add_body_field($types['node_example']);
// Load the instance definition for our content type's body
// http://api.drupal.org/api/function/field_info_instance/7
$body_instance = field_info_instance('node', 'body', 'node_example');
}
48. function node_example_install() {
$types = node_type_get_types();
node_add_body_field($types['node_example']);
// Load the instance definition for our content type's body
// http://api.drupal.org/api/function/field_info_instance/7
$body_instance = field_info_instance('node', 'body', 'node_example');
// Add our example_node_list view mode to the body instance display by
// instructing the body to display as a summary
$body_instance['type'] = 'text_summary_or_trimmed';
}
49. function node_example_install() {
$types = node_type_get_types();
node_add_body_field($types['node_example']);
// Load the instance definition for our content type's body
// http://api.drupal.org/api/function/field_info_instance/7
$body_instance = field_info_instance('node', 'body', 'node_example');
// Add our example_node_list view mode to the body instance display by
// instructing the body to display as a summary
$body_instance['type'] = 'text_summary_or_trimmed';
// Save our changes to the body field instance.
// http://api.drupal.org/api/function/field_update_instance/7
field_update_instance($body_instance);
}
50. function node_example_install() {
$types = node_type_get_types();
node_add_body_field($types['node_example']);
// Load the instance definition for our content type's body
// http://api.drupal.org/api/function/field_info_instance/7
$body_instance = field_info_instance('node', 'body', 'node_example');
// Add our example_node_list view mode to the body instance display by
// instructing the body to display as a summary
$body_instance['type'] = 'text_summary_or_trimmed';
// Save our changes to the body field instance.
// http://api.drupal.org/api/function/field_update_instance/7
field_update_instance($body_instance);
// Create all the fields we are adding to our content type.
// http://api.drupal.org/api/function/field_create_field/7
foreach (_node_example_installed_fields() as $field) {
field_create_field($field);
}
}
51. function node_example_install() {
$types = node_type_get_types();
node_add_body_field($types['node_example']);
// Load the instance definition for our content type's body
// http://api.drupal.org/api/function/field_info_instance/7
$body_instance = field_info_instance('node', 'body', 'node_example');
// Add our example_node_list view mode to the body instance display by
// instructing the body to display as a summary
$body_instance['type'] = 'text_summary_or_trimmed';
// Save our changes to the body field instance.
// http://api.drupal.org/api/function/field_update_instance/7
field_update_instance($body_instance);
// Create all the fields we are adding to our content type.
// http://api.drupal.org/api/function/field_create_field/7
foreach (_node_example_installed_fields() as $field) {
field_create_field($field);
}
// Create all the instances for our fields.
// http://api.drupal.org/api/function/field_create_instance/7
foreach (_node_example_installed_instances() as $instance) {
$instance['entity_type'] = 'node';
$instance['bundle'] = 'node_example';
field_create_instance($instance);
}
}
53. D7 *.install
• The node_example module defines and invokes
3 distinct fields
54. D7 *.install
• The node_example module defines and invokes
3 distinct fields
• We place these in a helper function so that it can
be called as needed in functions like
hook_install() and hook_uninstall()
66. D7 *.install
• hook_uninstall() is used to clean up the data
created with the node_example module
• hook_uninstall() deletes our fields and their
instances
67. D7 *.install
• hook_uninstall() is used to clean up the data
created with the node_example module
• hook_uninstall() deletes our fields and their
instances
• hook_uninstall() deletes our content type
68. D7 *.install
• hook_uninstall() is used to clean up the data
created with the node_example module
• hook_uninstall() deletes our fields and their
instances
• hook_uninstall() deletes our content type
• hook_uninstall purges field data from the system
70. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
}
71. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
// Delete all the nodes at once
// http://api.drupal.org/api/function/node_delete_multiple/7
node_delete_multiple($nids);
}
72. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
// Delete all the nodes at once
// http://api.drupal.org/api/function/node_delete_multiple/7
node_delete_multiple($nids);
// Loop over each of the fields defined by this module and delete
// all instances of the field, their data, and the field itself.
// http://api.drupal.org/api/function/field_delete_field/7
foreach (array_keys(_node_example_installed_fields()) as $field) {
field_delete_field($field);
}
}
73. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
// Delete all the nodes at once
// http://api.drupal.org/api/function/node_delete_multiple/7
node_delete_multiple($nids);
// Loop over each of the fields defined by this module and delete
// all instances of the field, their data, and the field itself.
// http://api.drupal.org/api/function/field_delete_field/7
foreach (array_keys(_node_example_installed_fields()) as $field) {
field_delete_field($field);
}
// Loop over any remaining field instances attached to the node_example
// content type (such as the body field) and delete them individually.
// http://api.drupal.org/api/function/field_delete_field/7
$instances = field_info_instances('node', 'node_example');
foreach ($instances as $instance_name => $instance) {
field_delete_instance($instance);
}
}
74. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
// Delete all the nodes at once
// http://api.drupal.org/api/function/node_delete_multiple/7
node_delete_multiple($nids);
// Loop over each of the fields defined by this module and delete
// all instances of the field, their data, and the field itself.
// http://api.drupal.org/api/function/field_delete_field/7
foreach (array_keys(_node_example_installed_fields()) as $field) {
field_delete_field($field);
}
// Loop over any remaining field instances attached to the node_example
// content type (such as the body field) and delete them individually.
// http://api.drupal.org/api/function/field_delete_field/7
$instances = field_info_instances('node', 'node_example');
foreach ($instances as $instance_name => $instance) {
field_delete_instance($instance);
}
// Delete our content type
// http://api.drupal.org/api/function/node_type_delete/7
node_type_delete('node_example');
}
75. function node_example_uninstall() {
// Gather all the example content that might have been created while this
// module was enabled. Simple selects still use db_query().
// http://api.drupal.org/api/function/db_query/7
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => 'node_example'));
$nids = array();
foreach ($result as $row) {
$nids[] = $row->nid;
}
// Delete all the nodes at once
// http://api.drupal.org/api/function/node_delete_multiple/7
node_delete_multiple($nids);
// Loop over each of the fields defined by this module and delete
// all instances of the field, their data, and the field itself.
// http://api.drupal.org/api/function/field_delete_field/7
foreach (array_keys(_node_example_installed_fields()) as $field) {
field_delete_field($field);
}
// Loop over any remaining field instances attached to the node_example
// content type (such as the body field) and delete them individually.
// http://api.drupal.org/api/function/field_delete_field/7
$instances = field_info_instances('node', 'node_example');
foreach ($instances as $instance_name => $instance) {
field_delete_instance($instance);
}
// Delete our content type
// http://api.drupal.org/api/function/node_type_delete/7
node_type_delete('node_example');
// Purge all field information
// http://api.drupal.org/api/function/field_purge_batch/7
field_purge_batch(1000);
}
78. D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
D6
79. D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
D6
• hook_node_info() informs Drupal about our
content type
80. D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
D6
• hook_node_info() informs Drupal about our
content type
• hook_menu() tells Drupal where our custom
page is going to live and how to build it
81. D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
D6
• hook_node_info() informs Drupal about our
content type
• hook_menu() tells Drupal where our custom
page is going to live and how to build it
• hook_help() provides help information for our
users
82.
83. /**
* Implements hook_node_info() to provide our node_example type.
*/
function node_example_node_info() {
return array(
'node_example' => array(
'name' => t('Example Node'),
'base' => 'node_example',
'description' => t('This is an example node type with a few fields.'),
'has_title' => TRUE,
),
);
}
84. /**
* Implements hook_node_info() to provide our node_example type.
*/
function node_example_node_info() {
return array(
'node_example' => array(
'name' => t('Example Node'),
'base' => 'node_example',
'description' => t('This is an example node type with a few fields.'),
'has_title' => TRUE,
),
);
}
/**
* Implements hook_menu().
*
* We are providing a default page to illustrate the use of our custom node view
* mode that will live at http://example.com/?q=examples/node_example
*/
function node_example_menu() {
$items['examples/node_example'] = array(
'page callback' => 'node_example_page',
'access arguments' => array('access content'),
'title' => 'Node Example',
);
return $items;
}
85. /**
* Implements hook_node_info() to provide our node_example type.
*/
function node_example_node_info() {
return array(
'node_example' => array(
'name' => t('Example Node'),
'base' => 'node_example',
'description' => t('This is an example node type with a few fields.'),
'has_title' => TRUE,
),
);
}
/**
* Implements hook_menu().
*
* We are providing a default page to illustrate the use of our custom node view
* mode that will live at http://example.com/?q=examples/node_example
*/
function node_example_menu() {
$items['examples/node_example'] = array(
'page callback' => 'node_example_page',
'access arguments' => array('access content'),
'title' => 'Node Example',
);
return $items;
}
/**
* Implements hook_help().
*/
function node_example_help($path, $arg) {
switch ($path) {
case 'examples/node_example':
return "<p>" . t(
"The Node Example module provides a custom node type.
You can create new nodes using the <a href='!nodeadd'>node add form</a>.
Nodes that you create will be displayed here.",
array('!nodeadd' => url('node/add/node-example'))
) . "</p>";
}
}
88. d7 *.module
• hook_form() is used to create the basic content
form
• hook_theme() informs Drupal of our theme
callbacks
89.
90. /**
* Implement hook_form() with the standard default form.
*/
function node_example_form($node, $form_state) {
return node_content_form($node, $form_state);
}
91. /**
* Implement hook_form() with the standard default form.
*/
function node_example_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_theme().
*
* This lets us tell Drupal about our theme functions and their arguments.
*/
function node_example_theme($existing, $type, $theme, $path) {
return array(
'example_node_color' => array(
'variables' => array('color' => NULL),
),
);
}
92. /**
* Implement hook_form() with the standard default form.
*/
function node_example_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_theme().
*
* This lets us tell Drupal about our theme functions and their arguments.
*/
function node_example_theme($existing, $type, $theme, $path) {
return array(
'example_node_color' => array(
'variables' => array('color' => NULL),
),
);
}
/**
* A custom theme function.
*
* By using this function to format our node-specific information, themes
* can override this presentation if they wish. This is a simplified theme
* function purely for illustrative purposes.
*/
function theme_example_node_color($variables) {
$output = '<span style="background-color: #ccc; padding: 1em; margin-bottom: 1em; float: left; color: ' .
$variables['color'] . '">' . $variables['color'] . '</span>';
return $output;
}
95. D7 *.module
• Now for the juicy D7 changes!!!
• hook_entity_info_alter() lets us modify the
node_entity to use our custom view mode
96. D7 *.module
• Now for the juicy D7 changes!!!
• hook_entity_info_alter() lets us modify the
node_entity to use our custom view mode
• hook_field_formatter_view() is where we place
the details of our custom view mode
97.
98. /**
* Implements hook_entity_info_alter().
*
* We need to modify the default node entity info by adding a new view mode to
* be used in functions like node_view() or node_build_content().
*
*/
function node_example_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['example_node_list'] = array(
'label' => t('Example Node List'),
'custom settings' => TRUE,
);
}
99. /**
* Implements hook_entity_info_alter().
*
* We need to modify the default node entity info by adding a new view mode to
* be used in functions like node_view() or node_build_content().
*
*/
function node_example_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['example_node_list'] = array(
'label' => t('Example Node List'),
'custom settings' => TRUE,
);
}
/**
* Implements hook_field_formatter_info().
*/
function node_example_field_formatter_info() {
return array(
'node_example_colors' => array(
'label' => t('Node Example Color Handle'),
'field types' => array('text'),
),
);
}
102. D7 *.module
• Last ... but certainly not least
• hook_field_formatter_view() is where we place
the details of our custom view mode
103.
104. /**
* Implements hook_field_formatter_view().
*
* @todo: We need to provide a formatter for the colors that a user is allowed to enter
* during node creation.
*/
function node_example_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'node_example_colors':
foreach ($items as $delta => $item) {
$element[$delta]['#type'] = 'markup';
$color = $item['safe_value'];
$element[$delta]['#markup'] = theme('example_node_color', array('color' => $color));
}
break;
}
return $element;
}
105. Informative Links
• The field API Tutorial - http://drupal.org/node/707832
• The Field API Glossary - http://drupal.org/node/443540
• Adding and Reusing a Field - http://drupal.org/node/
474420
• Making an Entity Fieldable - http://drupal.org/node/
474582
• The Examples Module - http://drupal.org/project/
examples
• Drupal API - http://api.drupal.org/
• Joachim’s http://drupal.org/project/field_convert