# Changing Context with the API

**URL:** <https://forums.sketchup.com/t/changing-context-with-the-api/98034>\
**Category:** Ruby API\
**Created:** [June 28, 2019, 1:39am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034 "2019-06-28T01:39:35Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 1:39am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/1 "2019-06-28T01:39:35Z")

</div>

I’m trying to figure out how to open up a group (change context) so that the user is presented with a group that is already active and then they can proceed to edit the geometry (lines and face) within this group.

I’m not seeing a way to do this with the API, but the documentation is so vast I’m sure I’m probably missing it. Can someone lead me in the right direction?

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 1:46am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/2 "2019-06-28T01:46:16Z")

</div>

I’m working on the foundation plugin right now and I am trying to provide a means whereby the user can define a new outline for the (polygon) slab-on-grade foundation.

The simplest thing that comes to mind is push all of the points that define the outline/perimeter of the foundation to a group that contains the face constructed from these points. Then the user can modify this face/lines as much as they like and once they are satisfied they click the save settings button of the accompanying HTML menu which then activates the ruby code that grabs this newly edited face and its points and regens the foundation.

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 3:18am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/3 "2019-06-28T03:18:26Z")

</div>

Per this thread:

> [@How to open (activate) a group via the ruby API](https://forums.sketchup.com/t/how-to-open-activate-a-group-via-the-ruby-api/43105/3):
>
> The concept of a Group or Component being “open for edit” or the “active context” comes purely from the GUI, where a user needs to access a Group or Component’s Entities to manipulate them. Are you trying to program something that will make a particular Group or Component active and then turn over control for the user to edit it via the GUI? Otherwise, as @TIG pointed out, your Ruby code can directly access the Entities collection of any Group or ComponentDefinition regardless of what is activ…

It looks like it may not be possible…

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 3:38am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/4 "2019-06-28T03:38:58Z")

</div>

`close_active` will allow me to get back to the root of the model.

`active_path` will give me a way of checking whether I need to use the previous method to jump back to the root of the model.

Found this gem by Eneroth:

> [@How to get the root Model in the scene?](https://forums.sketchup.com/t/how-to-get-the-root-model-in-the-scene/32088/21):
>
> btw, to esily detect if a ComponentDefinition is open for editing you can do this test def inside\_component?(definition) path = (Sketchup.active\_model.active\_path || [])# This method should in my view return an empty Array, not nil, when the model root is the active context. instance = path.last instance && instance.definition == definition end

However I don’t see a way of passing a group or component to a method which will then allow me to open up that entity for editing. There has got to be a way to do this, otherwise this is a major hole in the API.

---

<div class="post-metadata">

**Author:** ![eneroth3](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/eneroth3/32/1222_2.png) [@eneroth3](https://forums.sketchup.com/u/eneroth3)\
**Post date:** [June 28, 2019, 6:06am UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/5 "2019-06-28T06:06:06Z")

</div>

> [@medeek](#):
>
> otherwise this is a major hole in the API.

It is! It has been requested for years but apparently it’s quite hard to get it to work the way the backend is written. There are a few hacks like selecting a component and sending a virtual keystroke to enter through an OS API but then you have to implement it for Windows and MacOS separately and may need to update it if those OS APIs ever changes. I’m personally avoiding that kind of extra work.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [June 28, 2019, 3:19pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/6 "2019-06-28T15:19:34Z")

</div>

> [@medeek](#):
>
> I’m trying to figure out how to open up a group (change context) so that the user is presented with a group that is already active and then they can proceed to edit the geometry (lines and face) within this group.

**FYI** , the logged feature request (has posted “hacks” for Windows) …

> <https://github.com/SketchUp/api-issue-tracker/issues/129>
>
> \# Feature Request
> 
> In our extension "VR Sketch", the user in VR can edit the m…odel, including opening and closing groups and components. When the user in VR chooses to close a group, we call \`\`active\_model.close\_active\`\`. However, when she chooses to open a group, we have no official way to perform the operation in the SketchUp API.
> 
> We are currently using a gross and Windows-only hack, using a mixture of approaches, which I paste below in case somebody else is interested.
> 
> Maybe a more generally useful solution would be to let \`\`Sketchup.send\_action(id)\`\` trigger context menu items. The code below is a hack to dig out the id corresponding to the "Edit group" context menu. This id is variable, so we need to emulate the user clicking through the menu until he reaches the right menu command, and read the current id. I guess that the id is variable because the context menu is itself variable, and any number of extensions can add stuff to it. Still, if "edit group" and most of the other standard items had a fixed and public id, it would solve the problem.
> 
> 
> \`\`\`#! ruby
> require 'fiddle'
> require 'fiddle/types'
> require 'fiddle/import'
> \#...
> 
> module Kernel32
> extend Fiddle::Importer
> dlload 'kernel32.dll'
> include Fiddle::Win32Types
> extern 'DWORD GetCurrentThreadId()'
> end
> 
> module User32
> extend Fiddle::Importer
> dlload 'user32.dll'
> include Fiddle::Win32Types
> extern 'HWND GetAncestor(HWND, UINT)'
> #extern 'BOOL EnumThreadWindows(DWORD, WNDENUMPROC, LPARAM)'
> extern 'BOOL EnumThreadWindows(DWORD, PVOID, PVOID)'
> end
> 
> def hack\_prepare\_open\_group()
> # call this once, e.g. when your extension loads
> require 'Win32API'
> 
> @hack\_GetMenu = Win32API.new("user32.dll", "GetMenu", \['L'\], 'L')
> @hack\_GetMenuItemCount = Win32API.new("user32.dll", "GetMenuItemCount", \['L'\], 'I')
> @hack\_GetMenuItemID = Win32API.new("user32.dll", "GetMenuItemID", \['L', 'I'\], 'I')
> @hack\_GetSubMenu = Win32API.new("user32.dll", "GetSubMenu", \['L', 'I'\], 'L')
> @hack\_SendMessage = Win32API.new("user32.dll", "SendMessage", \['L', 'I', 'L', 'L'\], 'L')
> 
> # the fiddle parts are based on https://github.com/SketchUp/testup-2/blob/master/src/testup/win32.rb
> thread\_id = Kernel32.GetCurrentThreadId()
> main\_hwnd = 0
> 
> enumWindowsProc = Fiddle::Closure::BlockCaller.new(Fiddle::TYPE\_INT,
> \[Fiddle::TYPE\_VOIDP, Fiddle::TYPE\_VOIDP\]) { |hwnd, lparam|
> hwnd = User32.GetAncestor(hwnd, 3) # GA\_ROOTOWNER
> hmenu = @hack\_GetMenu.call(hwnd)
> next 1 if hmenu == 0
> heditmenu = @hack\_GetSubMenu.call(hmenu, 1)
> next 1 if heditmenu == 0
> menulength = @hack\_GetMenuItemCount.call(heditmenu)
> contextmenu = @hack\_GetSubMenu.call(heditmenu, menulength - 1)
> next 1 if contextmenu == 0
>                 
> main\_hwnd = hwnd
> next 0
> }
> User32.EnumThreadWindows(thread\_id, enumWindowsProc, 0)
> 
> UI.messagebox("Cannot get the top-level SketchUp window's Edit menu. Opening groups in VR will not work") if main\_hwnd == 0
> @hack\_hwnd = main\_hwnd
> end
> 
> def hack\_open\_group(model, grp)
> if (grp.is\_a? Sketchup::Group) || (grp.is\_a? Sketchup::ComponentInstance)
> found = 0
> model.active\_entities.each { |ent|
> if ent == grp
> found += 1
> end
> }
> if found \> 0
> Sketchup.active\_model.selection.clear
> Sketchup.active\_model.selection.add(grp)
> 
> hwnd = @hack\_hwnd
> hmenu = @hack\_GetMenu.call(hwnd)
> @hack\_SendMessage.call(hwnd, 0x0116, hmenu, 0)
> heditmenu = @hack\_GetSubMenu.call(hmenu, 1)
> @hack\_SendMessage.call(hwnd, 0x0117, heditmenu, 1)
> menulength = @hack\_GetMenuItemCount.call(heditmenu)
> contextmenu = @hack\_GetSubMenu.call(heditmenu, menulength - 1)
> id = @hack\_GetMenuItemID.call(contextmenu, 0)
> Sketchup.send\_action(id)
> else
> puts("open\_close\_group: group not in active\_entities")
> end
> else
> puts("open\_close\_group: not a group id")
> end
> end
> \`\`\`

---

<div class="post-metadata">

**Author:** ![eneroth3](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/eneroth3/32/1222_2.png) [@eneroth3](https://forums.sketchup.com/u/eneroth3)\
**Post date:** [June 28, 2019, 4:05pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/7 "2019-06-28T16:05:30Z")

</div>

And it’s worth mentioning that voting for issues using the 👍 symbol helps SU staff see what to prioritize.

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 5:56pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/8 "2019-06-28T17:56:11Z")

</div>

I’m trying to see if I can get the window hack to work but this line is problematic:

```
require 'win32ole'
UTIL = WIN32OLE::new(WScript.Shell)

```

It is giving me an error:

`Error: #<NameError: uninitialized constant WScript>`

or this error:

`dynamic constant assignment`

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 6:05pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/9 "2019-06-28T18:05:05Z")

</div>

This seems to work for Windows:

```
    ######################
	#
	# Open Group for Editing (Windows Only)

	if Sketchup.platform == :platform_win

    		ss = Sketchup.active_model.selection
		    ss.clear
      		ss.add(@maingroup)

    		if ss.length > 1
			UI.messagebox "Selection must be limited to one (1) Foundation Assembly."
		else
			if ss.empty?
        			UI.messagebox "No Foundation Assembly Selected."
        		else
				first_sel = ss[0]
				if first_sel.respond_to?(:definition)
					require "win32ole"
  					win32util = WIN32OLE.new('WScript.Shell')
					win32util.SendKeys('{ENTER}')
				end
      			end	
      		end
	else
		# Mac Solution?
	end

```

The only problem I’m having now is that right before I run this section of code I’m opening up an HTML menu so the focus is taken off of the main SU window. Now I just need to figure out how to bring the focus back to the main window, and also figure out a solution for MacOS.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [June 28, 2019, 6:36pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/10 "2019-06-28T18:36:40Z")

</div>

> [@medeek](#):
>
> ```ruby
> require 'win32ole'
> UTIL = WIN32OLE::new(WScript.Shell)
> 
> ```
> 
> It is giving me an error:
> 
> `Error: #<NameError: uninitialized constant WScript>`

Well the error message tells you exactly what you’re doing wrong. There is no Ruby constant (class or module) named WScript, ie yet defined within the Ruby **`ObjectSpace`**.

The first thing to do when you get such an error, would be to look up the WIN32OLE constructor method …

> **[Class: WIN32OLE (Ruby 2.5.1)](https://ruby-doc.org/stdlib-2.5.1/libdoc/win32ole/rdoc/WIN32OLE.html#method-c-new)**
>
> Class : WIN32OLE - Ruby 2.5.1

… which shows it is a server name (ie, a `String` object.)

> [@medeek](#):
>
> or this error:
> 
> `dynamic constant assignment`

This is a recent Ruby no-no … ie, most SketchUp versions using Ruby 2+.  
So Ruby no longer allows the assignment (or reassignment) of constants from within methods.  
Or at the least it is warning you, and soon will not be allowed in upcoming versions.

> [@medeek](#):
>
> The only problem I’m having now is that right before I run this section of code I’m opening up an HTML menu so the focus is taken off of the main SU window.

Another feature request “old as the hills” that has not yet been given us. Various hacks exist. (Opening a 1px x 1px webdialog offscreen, and then closing it returns focus to the main application window.)

> [@medeek](#):
>
> … and also figure out a solution for MacOS.

I’ve been chatting with @john_drivenupthewall how to send an enter (or return) to mac. He uses a utility called “cliclick”.

---

<div class="post-metadata">

**Author:** ![john\_drivenupthewall](https://avatars.discourse-cdn.com/v4/letter/j/c67d28/32.png) [@john\_drivenupthewall](https://forums.sketchup.com/u/john_drivenupthewall)\
**Post date:** [June 28, 2019, 6:44pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/11 "2019-06-28T18:44:46Z")

</div>

> [@medeek](#):
>
> The only problem I’m having now is…

I use this in some [on a mac]

```ruby
def focus_vp
  model = Sketchup.active_model.path
  Sketchup.open_file(model)
end

```

john

---

<div class="post-metadata">

**Author:** ![john\_drivenupthewall](https://avatars.discourse-cdn.com/v4/letter/j/c67d28/32.png) [@john\_drivenupthewall](https://forums.sketchup.com/u/john_drivenupthewall)\
**Post date:** [June 28, 2019, 6:56pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/12 "2019-06-28T18:56:24Z")

</div>

I grabbed that and then realised the next methods may also be relevant…

```ruby
    def edit_comp
      focus_vp
      cliclick = File.join(File.dirname( __dir__ ), 'bin', 'cliclick')
      %x["#{cliclick}" kd:shift t:C ku:shift]
    end

    def edit_grp
      focus_vp
      cliclick = File.join(File.dirname( __dir__ ), 'bin', 'cliclick')
      %x["#{cliclick}" kd:shift t:G ku:shift]
    end

#EDIT:
%x["#{cliclick}" kp:return] # will work for either

```

john

---

<div class="post-metadata">

**Author:** ![Fredo6](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/fredo6/32/77024_2.png) [@Fredo6](https://forums.sketchup.com/u/Fredo6)\
**Post date:** [June 28, 2019, 7:27pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/13 "2019-06-28T19:27:24Z")

</div>

> [@medeek](#):
>
> The only problem I’m having now is that right before I run this section of code I’m opening up an HTML menu so the focus is taken off of the main SU window. Now I just need to figure out how to bring the focus back to the main window, and also figure out a solution for MacOS.

If you are not within an active tool, then you just need to activate a dummy tool and then reset it to the previous tool. This is very fast.

```ruby
class DummyTool ; end

```

then

```ruby
Sketchup.active_model.select_tool DummyTool.new
Sketchup.active_model.select_tool nil

```

or if you think it is more appropriate

```ruby
Sketchup.active_model.tools.push_tool DummyTool.new
Sketchup.active_model.tools.pop_tool

```

If you are within your own tool, then you can exit your tool and reenter it, with a special state where you skip the _deactivate()_ and _activate()_. You of course need to have the instance of your Tool class somewhere.

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 7:39pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/14 "2019-06-28T19:39:15Z")

</div>

Here is what I have so far:

```
def open_group

	######################
	#
	# Open Group for Editing (Windows Only)

	if Sketchup.platform == :platform_win

    		ss = Sketchup.active_model.selection
		ss.clear
      		ss.add(@maingroup)

    		if ss.length > 1
			UI.messagebox "Selection must be limited to one (1) Foundation Assembly."
		else
			if ss.empty?
        			UI.messagebox "No Foundation Assembly Selected."
        		else
				first_sel = ss[0]
				if first_sel.respond_to?(:definition)
					require "win32ole"
					@win32util = WIN32OLE.new('WScript.Shell')
					MedeekMethods.activate_window
					@win32util.SendKeys('{ENTER}')

					# Edit nested group (not working)
					# ss.clear
      					# ss.add(@Temp_outline_group)
					# @win32util.SendKeys('{ENTER}')
				end
      			end	
      		end
	else
		# Mac Solution?
	end

	UI.stop_timer(@opentimer)

end

def activate_window
	caption = MedeekMethods.get_caption
  	@win32util.AppActivate caption
end

def get_caption
	su_version = Sketchup.version.to_i
  	if Sketchup.active_model.path.empty? # new model
		if Sketchup.is_pro?
			if su_version == '17'
				caption = "Untitled - SketchUp Pro 2017"
			elsif su_version == '18'
				caption = "Untitled - SketchUp Pro 2018"
			elsif su_version == '19'
				caption = "Untitled - SketchUp Pro 2019"
			else
				caption = "Untitled - SketchUp Pro"
			end
    		else
			caption = "Untitled - SketchUp Make 2017"
    		end
  	else
    		filename = File.basename(Sketchup.active_model.path)
    		if Sketchup.is_pro?
			if su_version == '17'
				caption = "#{filename} - SketchUp Pro 2017"
			elsif su_version == '18'
				caption = "#{filename} - SketchUp Pro 2018"
			elsif su_version == '19'
				caption = "#{filename} - SketchUp Pro 2019"
			else
				caption = "#{filename} - SketchUp Pro"
			end
    		else
			caption = "#{filename} - SketchUp Make 2017"
    		end
	end

	return caption
end

```

I have to call the open\_group method with a timer because of the HTML dialog so after my dialog is launched I call this:

`@opentimer = UI.start_timer(0.25, false) { open_group }`

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 7:41pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/15 "2019-06-28T19:41:50Z")

</div>

Note that I’m actually trying to edit a nested group with my main group. So I actually need to select the main group, open it then select the group inside and open it.

When I try to add the nested group to the selection set and then press enter it appears to jump me out of the editing of the main group so this is not working.

P.S. For now I’ve just commented out the logic that tries to open up the nested group. At least I can get one level deep. It is then up to the user to click into the nested group to edit it.

---

<div class="post-metadata">

**Author:** ![eneroth3](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/eneroth3/32/1222_2.png) [@eneroth3](https://forums.sketchup.com/u/eneroth3)\
**Post date:** [June 28, 2019, 8:13pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/16 "2019-06-28T20:13:03Z")

</div>

I think a quite big question is why you want to open a component. For e.g. a layer panel/outliner it is a required functionality, but perhaps your plugin can be designed to simply not do this.

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 8:59pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/17 "2019-06-28T20:59:51Z")

</div>

It is not an absolute necessity but it would be convenient to automatically drop the user into the group that needs to be modified.

Once I have this up and running I will post a video demonstrating its use to this thread as well so you can see what I am trying to accomplish.

---

<div class="post-metadata">

**Author:** ![eneroth3](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/eneroth3/32/1222_2.png) [@eneroth3](https://forums.sketchup.com/u/eneroth3)\
**Post date:** [June 28, 2019, 9:01pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/18 "2019-06-28T21:01:04Z")

</div>

Why do the user have to modify the group?

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 9:05pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/19 "2019-06-28T21:05:06Z")

</div>

Inside of this group is a face which defines the outline or perimeter of the slab-on-grade foundation. The user can edit this face to any geometry they like and then hit the update / commit button and the plugin will then utilize this updated face to regenerate the slab-on-grade foundation with the new perimeter.

Technically a user could just recreate their foundation from scratch with a new face (to define the outline) however people always want that parametric ability, so I have to provide it.

---

<div class="post-metadata">

**Author:** ![medeek](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/medeek/32/10675_2.png) [@medeek](https://forums.sketchup.com/u/medeek)\
**Post date:** [June 28, 2019, 9:30pm UTC](https://forums.sketchup.com/t/changing-context-with-the-api/98034/20 "2019-06-28T21:30:15Z")

</div>

I’m also using this method to jump out of the possible nested scenarios prior to regenerating the foundation:

```
def move_to_root
	path1 = (Sketchup.active_model.active_path || [])
	instance1 = path1.last
	if instance1 == @Temp_outline_group
		Sketchup.active_model.close_active

		path2 = (Sketchup.active_model.active_path || [])
		instance2 = path2.last
		if instance2 == @maingroup
			Sketchup.active_model.close_active
		end
	elsif instance1 == @maingroup
		Sketchup.active_model.close_active
	end
end

```

This is pretty basic stuff when you have the right methods available to you. It would really be nice if there was a method available to open a group or component rather than having to try and make it work with a hack job.

[Next page](https://forums.sketchup.com/t/changing-context-with-the-api/98034.md?page=2)
